From 1c31a519baec26328821913c9120bb228e4ca916 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 18 Apr 2018 16:03:17 -0300 Subject: [PATCH 01/36] Android Home screen access user_stories API to get domains - first implementation without filtering --- android/app/build.gradle | 3 + android/app/src/main/cpp/native.cpp | 5 ++ .../highfidelity/hifiinterface/HifiUtils.java | 2 + .../hifiinterface/HomeActivity.java | 2 +- .../provider/DomainProvider.java | 19 ++++ .../provider/UserStoryDomainProvider.java | 89 +++++++++++++++++++ .../hifiinterface/view/DomainAdapter.java | 27 +++++- 7 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java diff --git a/android/app/build.gradle b/android/app/build.gradle index 7a6f34b58b..fb0f43130c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -105,6 +105,9 @@ dependencies { implementation 'com.android.support:appcompat-v7:26.1.0' compile 'com.android.support:recyclerview-v7:26.1.0' + compile 'com.squareup.retrofit2:retrofit:2.4.0' + compile 'com.squareup.retrofit2:converter-gson:2.4.0' + implementation fileTree(include: ['*.jar'], dir: 'libs') } diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp index c71be76b3e..2e6da456eb 100644 --- a/android/app/src/main/cpp/native.cpp +++ b/android/app/src/main/cpp/native.cpp @@ -21,6 +21,7 @@ #include #include "AndroidHelper.h" +#include QAndroidJniObject __activity; @@ -204,4 +205,8 @@ JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_HifiUtils_getCurren return env->NewStringUTF(str.toLatin1().data()); } +JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_HifiUtils_protocolVersionSignature(JNIEnv *env, jobject instance) { + return env->NewStringUTF(protocolVersionsSignatureBase64().toLatin1().data()); } + +} \ No newline at end of file diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java index 15d716548f..901add4afa 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java @@ -20,4 +20,6 @@ public class HifiUtils { public native String getCurrentAddress(); + public native String protocolVersionSignature(); + } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index fd50d36c75..35cf49151d 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -87,7 +87,7 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On int numberOfColumns = 1; GridLayoutManager gridLayoutMgr = new GridLayoutManager(this, numberOfColumns); domainsView.setLayoutManager(gridLayoutMgr); - domainAdapter = new DomainAdapter(this); + domainAdapter = new DomainAdapter(this, ""); domainAdapter.setClickListener(new DomainAdapter.ItemClickListener() { @Override diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java new file mode 100644 index 0000000000..108adfbbe4 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java @@ -0,0 +1,19 @@ +package io.highfidelity.hifiinterface.provider; + +import java.util.List; + +import io.highfidelity.hifiinterface.view.DomainAdapter; + +/** + * Created by cduarte on 4/17/18. + */ + +public interface DomainProvider { + + void retrieve(Callback callback); + + interface Callback { + void retrieveOk(List domain); + void retrieveError(Exception e, String message); + } +} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java new file mode 100644 index 0000000000..d96f20ac15 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -0,0 +1,89 @@ +package io.highfidelity.hifiinterface.provider; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import io.highfidelity.hifiinterface.view.DomainAdapter; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * Created by cduarte on 4/17/18. + */ + +public class UserStoryDomainProvider implements DomainProvider { + + public static final String BASE_URL = "https://metaverse.highfidelity.com/"; + + private String mProtocol; + private Retrofit mRetrofit; + private UserStoryDomainProviderService mUserStoryDomainProviderService; + + public UserStoryDomainProvider(String protocol) { + mRetrofit = new Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + mUserStoryDomainProviderService = mRetrofit.create(UserStoryDomainProviderService.class); + mProtocol = protocol; + } + + @Override + public void retrieve(Callback callback) { + // TODO Call multiple pages + Call userStories = mUserStoryDomainProviderService.getUserStories(mProtocol); + userStories.enqueue(new retrofit2.Callback() { + + @Override + public void onResponse(Call call, Response response) { + UserStories userStories = response.body(); + if (userStories == null) { + callback.retrieveOk(new ArrayList<>(0)); + } + List domains = new ArrayList<>(userStories.total_entries); + userStories.user_stories.forEach(userStory -> { + // TODO Proper url creation (it can or can't have hifi + // TODO Or use host value from api? + domains.add(new DomainAdapter.Domain( + userStory.place_name, + "hifi://" + userStory.place_name + "/" + userStory.path, + userStory.thumbnail_url + )); + }); + callback.retrieveOk(domains); + } + + @Override + public void onFailure(Call call, Throwable t) { + callback.retrieveError(new Exception(t), t.getMessage()); + } + + }); + } + + public interface UserStoryDomainProviderService { + @GET("api/v1/user_stories") + Call getUserStories(@Query("protocol") String protocol); + } + + class UserStory { + public UserStory() {} + String place_name; + String path; + String thumbnail_url; + } + + class UserStories { + String status; + int current_page; + int total_pages; + int total_entries; + List user_stories; + } +} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 1129ec586f..f8b4e73cd1 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -19,6 +19,8 @@ import java.util.ArrayList; import java.util.List; import io.highfidelity.hifiinterface.R; +import io.highfidelity.hifiinterface.provider.DomainProvider; +import io.highfidelity.hifiinterface.provider.UserStoryDomainProvider; /** * Created by Gabriel Calero & Cristian Duarte on 3/20/18. @@ -30,12 +32,13 @@ public class DomainAdapter extends RecyclerView.Adapter domain) { + mDomains = domain.toArray(mDomains); + notifyDataSetChanged(); + } + + @Override + public void retrieveError(Exception e, String message) { + // + Log.e("DOMAINS", message, e); + } + }); + } + + private void loadDomainsLocalFile() { try { JSONObject json = new JSONObject(loadJSONFromAsset()); JSONArray hifiDomains = json.getJSONArray("hifi_domains"); From 0ae564b9b6866939355f6fe5941c1ae9fb4bb521 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 18 Apr 2018 21:24:58 -0300 Subject: [PATCH 02/36] Android - Home screen has search. First implementation that retrieves 10 pages of concurrency from the user_stories API and allows filtering --- .../hifiinterface/HomeActivity.java | 17 +- .../hifiinterface/provider/Callback.java | 9 + .../provider/DomainProvider.java | 4 +- .../provider/UserStoryDomainProvider.java | 175 ++++++++++++++++-- .../hifiinterface/view/DomainAdapter.java | 12 +- .../app/src/main/res/layout/content_home.xml | 10 +- 6 files changed, 200 insertions(+), 27 deletions(-) create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/provider/Callback.java diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 4a75eef98f..943c4cfaec 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -12,10 +12,12 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.text.Editable; +import android.text.TextWatcher; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.SearchView; +import android.widget.EditText; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; @@ -97,7 +99,7 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On }); domainsView.setAdapter(domainAdapter); - SearchView searchView = findViewById(R.id.searchView); + EditText searchView = findViewById(R.id.searchView); int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null); View searchPlate = searchView.findViewById(searchPlateId); if (searchPlate!=null) { @@ -106,7 +108,18 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On TextView searchTextView = searchView.findViewById(searchTextId); searchTextView.setTextAppearance(R.style.SearchText); } + searchView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + + @Override + public void afterTextChanged(Editable editable) { + domainAdapter.loadDomains(editable.toString()); + } + }); updateLoginMenu(); } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/Callback.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/Callback.java new file mode 100644 index 0000000000..64ca6da816 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/Callback.java @@ -0,0 +1,9 @@ +package io.highfidelity.hifiinterface.provider; + +/** + * Created by cduarte on 4/18/18. + */ + +public interface Callback { + public void callback(T t); +} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java index 108adfbbe4..7a2101a229 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/DomainProvider.java @@ -10,9 +10,9 @@ import io.highfidelity.hifiinterface.view.DomainAdapter; public interface DomainProvider { - void retrieve(Callback callback); + void retrieve(String filterText, DomainCallback domainCallback); - interface Callback { + interface DomainCallback { void retrieveOk(List domain); void retrieveError(Exception e, String message); } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java index d96f20ac15..0e2c190a14 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -1,12 +1,16 @@ package io.highfidelity.hifiinterface.provider; +import android.util.Log; +import android.util.MutableInt; + import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.function.BinaryOperator; import java.util.function.Consumer; import io.highfidelity.hifiinterface.view.DomainAdapter; import retrofit2.Call; -import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; @@ -21,10 +25,18 @@ public class UserStoryDomainProvider implements DomainProvider { public static final String BASE_URL = "https://metaverse.highfidelity.com/"; + private static final String INCLUDE_ACTIONS_FOR_PLACES = "concurrency"; + private static final String INCLUDE_ACTIONS_FOR_FULL_SEARCH = "concurrency,announcements,snapshot"; + private static final int MAX_PAGES_TO_GET = 10; + private String mProtocol; private Retrofit mRetrofit; private UserStoryDomainProviderService mUserStoryDomainProviderService; + private boolean startedToGetFromAPI = false; + private List allStories; // All retrieved stories from the API + private List suggestions; // Filtered places to show + public UserStoryDomainProvider(String protocol) { mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) @@ -32,36 +44,144 @@ public class UserStoryDomainProvider implements DomainProvider { .build(); mUserStoryDomainProviderService = mRetrofit.create(UserStoryDomainProviderService.class); mProtocol = protocol; + allStories = new ArrayList<>(); + suggestions = new ArrayList<>(); + } + + private void fillDestinations(String filterText, DomainCallback domainCallback) { + StoriesFilter filter = new StoriesFilter(filterText); + final MutableInt counter = new MutableInt(0); + allStories.clear(); + getUserStoryPage(1, + e -> { + allStories.subList(counter.value, allStories.size()).forEach(userStory -> { + // TODO Report error? e + filter.filterOrAdd(userStory); + // TODO Visibility stuff according to size of suggestions? + }); + if (domainCallback != null) { + domainCallback.retrieveOk(suggestions); //ended + } + }, + a -> { + allStories.forEach(userStory -> { + counter.value++; + filter.filterOrAdd(userStory); + // TODO Visibility stuff according to size of suggestions? + }); + } + ); + } + + private void handleError(String url, Throwable t, Callback restOfPagesCallback) { + restOfPagesCallback.callback(new Exception("Error accessing url [" + url + "]", t)); + } + + private void getUserStoryPage(int pageNumber, Callback restOfPagesCallback, Callback firstPageCallback) { + Call userStories = mUserStoryDomainProviderService.getUserStories( + INCLUDE_ACTIONS_FOR_PLACES, + "open", + true, + mProtocol, + pageNumber); + userStories.enqueue(new retrofit2.Callback() { + @Override + public void onResponse(Call call, Response response) { + UserStories data = response.body(); + allStories.addAll(data.user_stories); + if (data.current_page < data.total_pages && data.current_page <= MAX_PAGES_TO_GET) { + if (pageNumber == 1 && firstPageCallback!=null) { + firstPageCallback.callback(null); + } + getUserStoryPage(pageNumber + 1, restOfPagesCallback, null); + return; + } + restOfPagesCallback.callback(null); + } + + @Override + public void onFailure(Call call, Throwable t) { + handleError(call.request().url().toString(), t, restOfPagesCallback); + } + }); + } + + private class StoriesFilter { + String[] mWords = new String[]{}; + public StoriesFilter(String filterText) { + mWords = filterText.toUpperCase().split("\\s+"); + } + + private boolean matches(UserStory story) { + if (mWords.length<=0) return true; + + boolean res = true; + for (String word: mWords) { + res = res && story.searchText().contains(word); + if (!res) break; + } + + return res; + } + + private void addToSuggestions(UserStory story) { + suggestions.add(story.toDomain()); + } + + public void filterOrAdd(UserStory story) { + if (matches(story)) { + addToSuggestions(story); + } + } + } + + private void filterChoicesByText(String filterText, DomainCallback domainCallback) { + suggestions.clear(); + StoriesFilter storiesFilter = new StoriesFilter(filterText); + allStories.forEach(story -> { + storiesFilter.filterOrAdd(story); + }); + domainCallback.retrieveOk(suggestions); } @Override - public void retrieve(Callback callback) { + public synchronized void retrieve(String filterText, DomainCallback domainCallback) { + if (!startedToGetFromAPI) { + startedToGetFromAPI = true; + fillDestinations(filterText, domainCallback); + } else { + filterChoicesByText(filterText, domainCallback); + } + } + + public void retrieveNot(DomainCallback domainCallback) { // TODO Call multiple pages - Call userStories = mUserStoryDomainProviderService.getUserStories(mProtocol); + Call userStories = mUserStoryDomainProviderService.getUserStories( + INCLUDE_ACTIONS_FOR_PLACES, + "open", + true, + mProtocol, + 1); + + Log.d("API-USER-STORY-DOMAINS", "Protocol [" + mProtocol + "] include_actions [" + INCLUDE_ACTIONS_FOR_PLACES + "]"); userStories.enqueue(new retrofit2.Callback() { @Override public void onResponse(Call call, Response response) { UserStories userStories = response.body(); if (userStories == null) { - callback.retrieveOk(new ArrayList<>(0)); + domainCallback.retrieveOk(new ArrayList<>(0)); } List domains = new ArrayList<>(userStories.total_entries); userStories.user_stories.forEach(userStory -> { - // TODO Proper url creation (it can or can't have hifi - // TODO Or use host value from api? - domains.add(new DomainAdapter.Domain( - userStory.place_name, - "hifi://" + userStory.place_name + "/" + userStory.path, - userStory.thumbnail_url - )); + domains.add(userStory.toDomain()); }); - callback.retrieveOk(domains); + domainCallback.retrieveOk(domains); } @Override public void onFailure(Call call, Throwable t) { - callback.retrieveError(new Exception(t), t.getMessage()); + domainCallback.retrieveError(new Exception(t), t.getMessage()); } }); @@ -69,7 +189,11 @@ public class UserStoryDomainProvider implements DomainProvider { public interface UserStoryDomainProviderService { @GET("api/v1/user_stories") - Call getUserStories(@Query("protocol") String protocol); + Call getUserStories(@Query("include_actions") String includeActions, + @Query("restriction") String restriction, + @Query("require_online") boolean requireOnline, + @Query("protocol") String protocol, + @Query("page") int pageNumber); } class UserStory { @@ -77,6 +201,28 @@ public class UserStoryDomainProvider implements DomainProvider { String place_name; String path; String thumbnail_url; + String place_id; + String domain_id; + private String searchText; + + // New fields? tags, description + + String searchText() { + if (searchText==null) { + searchText = place_name == null? "" : place_name.toUpperCase(); + } + return searchText; + } + DomainAdapter.Domain toDomain() { + // TODO Proper url creation (it can or can't have hifi + // TODO Or use host value from api? + DomainAdapter.Domain domain = new DomainAdapter.Domain( + place_name, + "hifi://" + place_name + "/" + path, + thumbnail_url + ); + return domain; + } } class UserStories { @@ -86,4 +232,5 @@ public class UserStoryDomainProvider implements DomainProvider { int total_entries; List user_stories; } + } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index f8b4e73cd1..13e757db94 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -33,6 +33,7 @@ public class DomainAdapter extends RecyclerView.Adapter domain) { + mDomains = new Domain[domain.size()]; mDomains = domain.toArray(mDomains); notifyDataSetChanged(); } diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index f25d9d8f7b..217e922a8d 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -28,14 +28,14 @@ android:layout_height="wrap_content" android:background="@color/backgroundDark"/> - + android:layout_height="match_parent" /> From e784d45b244750f30fccfd77e9cecd9186374fdf Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 18 Apr 2018 21:40:37 -0300 Subject: [PATCH 03/36] Android Search - Enter goes to what was typed in the search field (uses it as an address) --- .../hifiinterface/GotoActivity.java | 13 +------------ .../highfidelity/hifiinterface/HifiUtils.java | 19 +++++++++++++++++++ .../hifiinterface/HomeActivity.java | 15 +++++++++++++++ .../app/src/main/res/layout/content_home.xml | 2 ++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/GotoActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/GotoActivity.java index f1ecc21d84..125483da94 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/GotoActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/GotoActivity.java @@ -11,9 +11,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.EditText; -import java.net.URI; -import java.net.URISyntaxException; - public class GotoActivity extends AppCompatActivity { public static final String PARAM_DOMAIN_URL = "domain_url"; @@ -60,15 +57,7 @@ public class GotoActivity extends AppCompatActivity { private void actionGo() { String urlString = mUrlEditText.getText().toString(); if (!urlString.trim().isEmpty()) { - URI uri; - try { - uri = new URI(urlString); - } catch (URISyntaxException e) { - return; - } - if (uri.getScheme()==null || uri.getScheme().isEmpty()) { - urlString = "hifi://" + urlString; - } + urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString); Intent intent = new Intent(); intent.putExtra(GotoActivity.PARAM_DOMAIN_URL, urlString); diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java index 901add4afa..c26a935b1f 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java @@ -1,5 +1,8 @@ package io.highfidelity.hifiinterface; +import java.net.URI; +import java.net.URISyntaxException; + /** * Created by Gabriel Calero & Cristian Duarte on 4/13/18. */ @@ -18,6 +21,22 @@ public class HifiUtils { return instance; } + public String sanitizeHifiUrl(String urlString) { + urlString = urlString.trim(); + if (!urlString.isEmpty()) { + URI uri; + try { + uri = new URI(urlString); + } catch (URISyntaxException e) { + return urlString; + } + if (uri.getScheme() == null || uri.getScheme().isEmpty()) { + urlString = "hifi://" + urlString; + } + } + return urlString; + } + public native String getCurrentAddress(); public native String protocolVersionSignature(); diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 943c4cfaec..14dec0ea74 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -14,6 +14,7 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -120,6 +121,20 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On domainAdapter.loadDomains(editable.toString()); } }); + searchView.setOnKeyListener(new View.OnKeyListener() { + @Override + public boolean onKey(View view, int i, KeyEvent keyEvent) { + if (i == KeyEvent.KEYCODE_ENTER) { + String urlString = searchView.getText().toString(); + if (!urlString.trim().isEmpty()) { + urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString); + } + gotoDomain(urlString); + return true; + } + return false; + } + }); updateLoginMenu(); } diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index 217e922a8d..0a3340c04a 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -36,6 +36,8 @@ android:gravity="center_vertical|end" android:paddingStart="32dp" android:paddingEnd="32dp" + android:inputType="textUri" + android:imeOptions="actionGo" /> Date: Thu, 19 Apr 2018 11:47:11 -0300 Subject: [PATCH 04/36] Android - Use images in domains list --- android/app/build.gradle | 1 + .../highfidelity/hifiinterface/HifiUtils.java | 18 ++++++++++++++++++ .../provider/UserStoryDomainProvider.java | 6 ++++-- .../hifiinterface/view/DomainAdapter.java | 8 +++++++- .../app/src/main/res/layout/domain_view.xml | 1 + 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index fb0f43130c..b2b3bcd772 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -107,6 +107,7 @@ dependencies { compile 'com.squareup.retrofit2:retrofit:2.4.0' compile 'com.squareup.retrofit2:converter-gson:2.4.0' + implementation 'com.squareup.picasso:picasso:2.71828' implementation fileTree(include: ['*.jar'], dir: 'libs') } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java index c26a935b1f..368862bc49 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java @@ -9,6 +9,8 @@ import java.net.URISyntaxException; public class HifiUtils { + public static final String BASE_URL = "https://metaverse.highfidelity.com"; + private static HifiUtils instance; private HifiUtils() { @@ -37,6 +39,22 @@ public class HifiUtils { return urlString; } + public String absoluteHifiAssetUrl(String urlString) { + urlString = urlString.trim(); + if (!urlString.isEmpty()) { + URI uri; + try { + uri = new URI(urlString); + } catch (URISyntaxException e) { + return urlString; + } + if (uri.getScheme() == null || uri.getScheme().isEmpty()) { + urlString = BASE_URL + urlString; + } + } + return urlString; + } + public native String getCurrentAddress(); public native String protocolVersionSignature(); diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java index 0e2c190a14..6b1452ed34 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.function.BinaryOperator; import java.util.function.Consumer; +import io.highfidelity.hifiinterface.HifiUtils; import io.highfidelity.hifiinterface.view.DomainAdapter; import retrofit2.Call; import retrofit2.Response; @@ -216,10 +217,11 @@ public class UserStoryDomainProvider implements DomainProvider { DomainAdapter.Domain toDomain() { // TODO Proper url creation (it can or can't have hifi // TODO Or use host value from api? + String absoluteThumbnailUrl = HifiUtils.getInstance().absoluteHifiAssetUrl(thumbnail_url); DomainAdapter.Domain domain = new DomainAdapter.Domain( place_name, - "hifi://" + place_name + "/" + path, - thumbnail_url + HifiUtils.getInstance().sanitizeHifiUrl(place_name) + "/" + path, + absoluteThumbnailUrl ); return domain; } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 13e757db94..6ea7db076a 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -1,6 +1,7 @@ package io.highfidelity.hifiinterface.view; import android.content.Context; +import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; @@ -9,6 +10,8 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import com.squareup.picasso.Picasso; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -119,7 +122,10 @@ public class DomainAdapter extends RecyclerView.Adapter Date: Thu, 19 Apr 2018 16:06:59 -0300 Subject: [PATCH 05/36] Android - Search - Remove unused buttons, add text background, search hint italic --- .../app/src/main/res/layout/content_home.xml | 7 +-- .../app/src/main/res/layout/domain_view.xml | 60 ++++--------------- android/app/src/main/res/values/colors.xml | 1 + android/app/src/main/res/values/strings.xml | 1 + 4 files changed, 15 insertions(+), 54 deletions(-) diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index 0a3340c04a..5e0c1babda 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -26,16 +26,18 @@ android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" + android:visibility="gone" android:background="@color/backgroundDark"/> @@ -53,7 +55,6 @@ android:id="@+id/rvDomains" android:layout_width="match_parent" android:layout_height="match_parent" /> - - - diff --git a/android/app/src/main/res/layout/domain_view.xml b/android/app/src/main/res/layout/domain_view.xml index 436c0e8711..ebcc831f05 100644 --- a/android/app/src/main/res/layout/domain_view.xml +++ b/android/app/src/main/res/layout/domain_view.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="113dp" + android:layout_height="170dp" android:paddingLeft="14dp" android:paddingRight="14dp" android:paddingTop="4dp" @@ -18,58 +18,18 @@ - - - - - - - - + \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 6e756a85fa..bad51ce697 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -15,4 +15,5 @@ #9e9e9e #F2F2F2 #FF7171 + #7F000000 diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 14f9100f07..a0dd650da7 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -20,5 +20,6 @@ Forgot password? Username or password incorrect. Logging into High Fidelity + Search for a place by name From af785d60727a8e27c58dd7b8e3a2d1e052139180 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Thu, 19 Apr 2018 17:22:53 -0300 Subject: [PATCH 06/36] Android - Search - Cleanup tabs code and code in general. Show 'no places' message when no results from search. --- .../hifiinterface/HomeActivity.java | 83 +++++++--------- .../provider/UserStoryDomainProvider.java | 10 +- .../hifiinterface/view/DomainAdapter.java | 40 +++++--- .../app/src/main/res/layout/content_home.xml | 96 +++++++------------ android/app/src/main/res/values/strings.xml | 3 +- 5 files changed, 102 insertions(+), 130 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index aa68818b05..c4207de898 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -19,8 +19,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; -import android.widget.TabHost; -import android.widget.TabWidget; import android.widget.TextView; import io.highfidelity.hifiinterface.view.DomainAdapter; @@ -38,9 +36,11 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On public static final int ENTER_DOMAIN_URL = 1; - private DomainAdapter domainAdapter; + private DomainAdapter mDomainAdapter; private DrawerLayout mDrawerLayout; private NavigationView mNavigationView; + private RecyclerView mDomainsView; + private TextView searchNoResultsView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -59,46 +59,40 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On mNavigationView = (NavigationView) findViewById(R.id.nav_view); mNavigationView.setNavigationItemSelectedListener(this); - TabHost tabs = (TabHost)findViewById(R.id.tabhost); - tabs.setup(); + searchNoResultsView = findViewById(R.id.searchNoResultsView); - TabHost.TabSpec spec=tabs.newTabSpec("featured"); - spec.setContent(R.id.featured); - spec.setIndicator(getString(R.string.featured)); - tabs.addTab(spec); - - spec = tabs.newTabSpec("popular"); - spec.setContent(R.id.popular); - spec.setIndicator(getString(R.string.popular)); - tabs.addTab(spec); - - spec = tabs.newTabSpec("bookmarks"); - spec.setContent(R.id.bookmarks); - spec.setIndicator(getString(R.string.bookmarks)); - tabs.addTab(spec); - - tabs.setCurrentTab(0); - - TabWidget tabwidget=tabs.getTabWidget(); - for(int i=0; i { + if (i == KeyEvent.KEYCODE_ENTER) { + String urlString = searchView.getText().toString(); + if (!urlString.trim().isEmpty()) { + urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString); } - return false; + gotoDomain(urlString); + return true; } + return false; }); updateLoginMenu(); diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java index 6b1452ed34..32980e6547 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -4,10 +4,7 @@ import android.util.Log; import android.util.MutableInt; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.function.BinaryOperator; -import java.util.function.Consumer; import io.highfidelity.hifiinterface.HifiUtils; import io.highfidelity.hifiinterface.view.DomainAdapter; @@ -56,9 +53,7 @@ public class UserStoryDomainProvider implements DomainProvider { getUserStoryPage(1, e -> { allStories.subList(counter.value, allStories.size()).forEach(userStory -> { - // TODO Report error? e filter.filterOrAdd(userStory); - // TODO Visibility stuff according to size of suggestions? }); if (domainCallback != null) { domainCallback.retrieveOk(suggestions); //ended @@ -68,7 +63,6 @@ public class UserStoryDomainProvider implements DomainProvider { allStories.forEach(userStory -> { counter.value++; filter.filterOrAdd(userStory); - // TODO Visibility stuff according to size of suggestions? }); } ); @@ -91,7 +85,7 @@ public class UserStoryDomainProvider implements DomainProvider { UserStories data = response.body(); allStories.addAll(data.user_stories); if (data.current_page < data.total_pages && data.current_page <= MAX_PAGES_TO_GET) { - if (pageNumber == 1 && firstPageCallback!=null) { + if (pageNumber == 1 && firstPageCallback != null) { firstPageCallback.callback(null); } getUserStoryPage(pageNumber + 1, restOfPagesCallback, null); @@ -209,7 +203,7 @@ public class UserStoryDomainProvider implements DomainProvider { // New fields? tags, description String searchText() { - if (searchText==null) { + if (searchText == null) { searchText = place_name == null? "" : place_name.toUpperCase(); } return searchText; diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 6ea7db076a..4c0f54e354 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -37,17 +37,7 @@ public class DomainAdapter extends RecyclerView.Adapter - + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/searchView" + android:layout_marginTop="32dp" + android:text="@string/search_no_results" + android:visibility="gone" + /> - - - - - - - - - - - - - - - - - - - + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index a0dd650da7..2cd8944b6f 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -21,5 +21,6 @@ Username or password incorrect. Logging into High Fidelity Search for a place by name - + Loading places… + No places exist with that name From 54997873854c76e986f8d0efd65883a2023dd884 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 20 Apr 2018 19:26:53 -0300 Subject: [PATCH 07/36] Android - TMP PATCH - Do not deactivate DisplayPlugin as it makes the black screen problem --- .../io/highfidelity/hifiinterface/InterfaceActivity.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java index 8cd5076a7a..2edab94374 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java @@ -127,13 +127,15 @@ public class InterfaceActivity extends QtActivity { @Override protected void onStart() { super.onStart(); - nativeEnterForeground(); + // TODO Fix displayPlugin deactivate so it doesn't leave us with a black screen Interface + //nativeEnterForeground(); } @Override protected void onStop() { super.onStop(); - nativeEnterBackground(); + // TODO Fix displayPlugin deactivate so it doesn't leave us with a black screen Interface + //nativeEnterBackground(); } @Override From 8e7d14a8e362eb8973a8e68ada1bb9edf25659af Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 23 Apr 2018 13:16:27 -0300 Subject: [PATCH 08/36] Android - Search - Search icon and clear button + UI background matches design --- .../hifiinterface/HomeActivity.java | 36 ++++++++++++------- .../provider/UserStoryDomainProvider.java | 1 + .../app/src/main/res/drawable/ic_clear.xml | 12 +++++++ .../app/src/main/res/drawable/ic_search.xml | 4 +++ .../app/src/main/res/layout/content_home.xml | 26 +++++++++++++- android/app/src/main/res/values/colors.xml | 2 +- 6 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_clear.xml create mode 100644 android/app/src/main/res/drawable/ic_search.xml diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 1257ad2b52..4227de4ac9 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -1,7 +1,6 @@ package io.highfidelity.hifiinterface; import android.content.Intent; -import android.graphics.Color; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.NavigationView; @@ -19,6 +18,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; +import android.widget.ImageView; import android.widget.TextView; import io.highfidelity.hifiinterface.view.DomainAdapter; @@ -41,6 +41,9 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On private NavigationView mNavigationView; private RecyclerView mDomainsView; private TextView searchNoResultsView; + private ImageView mSearchIconView; + private ImageView mClearSearch; + private EditText mSearchView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -94,16 +97,11 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On }); mDomainsView.setAdapter(mDomainAdapter); - EditText searchView = findViewById(R.id.searchView); - int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null); - View searchPlate = searchView.findViewById(searchPlateId); - if (searchPlate != null) { - searchPlate.setBackgroundColor (Color.TRANSPARENT); - int searchTextId = searchPlate.getContext ().getResources ().getIdentifier ("android:id/search_src_text", null, null); - TextView searchTextView = searchView.findViewById(searchTextId); - searchTextView.setTextAppearance(R.style.SearchText); - } - searchView.addTextChangedListener(new TextWatcher() { + mSearchView = findViewById(R.id.searchView); + mSearchIconView = findViewById(R.id.search_mag_icon); + mClearSearch = findViewById(R.id.search_clear); + + mSearchView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @@ -113,11 +111,18 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On @Override public void afterTextChanged(Editable editable) { mDomainAdapter.loadDomains(editable.toString()); + if(editable.length()>0) { + mSearchIconView.setVisibility(View.GONE); + mClearSearch.setVisibility(View.VISIBLE); + } else { + mSearchIconView.setVisibility(View.VISIBLE); + mClearSearch.setVisibility(View.GONE); + } } }); - searchView.setOnKeyListener((view, i, keyEvent) -> { + mSearchView.setOnKeyListener((view, i, keyEvent) -> { if (i == KeyEvent.KEYCODE_ENTER) { - String urlString = searchView.getText().toString(); + String urlString = mSearchView.getText().toString(); if (!urlString.trim().isEmpty()) { urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString); } @@ -126,6 +131,7 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On } return false; }); + updateLoginMenu(); } @@ -215,4 +221,8 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On public void onBackPressed() { finishAffinity(); } + + public void onSearchClear(View view) { + mSearchView.setText(""); + } } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java index 32980e6547..50202234e9 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -79,6 +79,7 @@ public class UserStoryDomainProvider implements DomainProvider { true, mProtocol, pageNumber); + Log.d("API-USER-STORY-DOMAINS", "Protocol [" + mProtocol + "] include_actions [" + INCLUDE_ACTIONS_FOR_PLACES + "]"); userStories.enqueue(new retrofit2.Callback() { @Override public void onResponse(Call call, Response response) { diff --git a/android/app/src/main/res/drawable/ic_clear.xml b/android/app/src/main/res/drawable/ic_clear.xml new file mode 100644 index 0000000000..94efe2bbdb --- /dev/null +++ b/android/app/src/main/res/drawable/ic_clear.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_search.xml b/android/app/src/main/res/drawable/ic_search.xml new file mode 100644 index 0000000000..099c8ea953 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_search.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index 2b6f8d94d6..59a7abb66c 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -17,13 +17,37 @@ android:background="@drawable/search_bg" android:gravity="center_vertical|end" android:paddingStart="32dp" - android:paddingEnd="32dp" + android:paddingEnd="56dp" android:fontFamily="@font/raleway" android:hint="@string/search_hint" android:inputType="textUri" android:imeOptions="actionGo" /> + + + + #ffffff - #272727 + @color/backgroundLight #000000 #54D7FD #E3E3E3 From 52ef935acb850c755b6c2afe3db10b0d93e072b4 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 23 Apr 2018 21:43:27 -0300 Subject: [PATCH 09/36] Android - Search - Ripple effect on items and rounded corners using CardView --- android/app/build.gradle | 1 + .../app/src/main/res/drawable/domain_bg.xml | 10 --- .../app/src/main/res/layout/activity_home.xml | 2 +- .../app/src/main/res/layout/domain_view.xml | 67 +++++++++++-------- android/app/src/main/res/values/colors.xml | 4 +- android/app/src/main/res/values/dimens.xml | 1 + 6 files changed, 43 insertions(+), 42 deletions(-) delete mode 100644 android/app/src/main/res/drawable/domain_bg.xml diff --git a/android/app/build.gradle b/android/app/build.gradle index b2b3bcd772..c63f481f8c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -104,6 +104,7 @@ dependencies { implementation 'com.android.support:design:26.1.0' implementation 'com.android.support:appcompat-v7:26.1.0' compile 'com.android.support:recyclerview-v7:26.1.0' + compile 'com.android.support:cardview-v7:26.1.0' compile 'com.squareup.retrofit2:retrofit:2.4.0' compile 'com.squareup.retrofit2:converter-gson:2.4.0' diff --git a/android/app/src/main/res/drawable/domain_bg.xml b/android/app/src/main/res/drawable/domain_bg.xml deleted file mode 100644 index d30d6413e1..0000000000 --- a/android/app/src/main/res/drawable/domain_bg.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/layout/activity_home.xml b/android/app/src/main/res/layout/activity_home.xml index ea24faf823..c399ac16ec 100644 --- a/android/app/src/main/res/layout/activity_home.xml +++ b/android/app/src/main/res/layout/activity_home.xml @@ -18,7 +18,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:background="?attr/colorPrimary" + android:background="?attr/colorPrimaryDark" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> diff --git a/android/app/src/main/res/layout/domain_view.xml b/android/app/src/main/res/layout/domain_view.xml index ebcc831f05..2c2a36665f 100644 --- a/android/app/src/main/res/layout/domain_view.xml +++ b/android/app/src/main/res/layout/domain_view.xml @@ -1,35 +1,44 @@ - - + android:layout_marginStart="14dp" + android:layout_marginEnd="14dp" + android:layout_marginTop="4dp" + android:layout_marginBottom="4dp" + android:foreground="@drawable/rippleable" + android:clickable="true" + android:focusable="true" + android:elevation="0dp" + app:cardElevation="0dp" + app:cardCornerRadius="@dimen/item_corner_radius"> - - - \ No newline at end of file + android:layout_height="match_parent"> + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 92e9f859ee..4dfc98d3ad 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -2,7 +2,7 @@ #ffffff @color/backgroundLight - #000000 + @color/backgroundDark #54D7FD #E3E3E3 #575757 @@ -15,5 +15,5 @@ #9e9e9e #F2F2F2 #FF7171 - #7F000000 + #99000000 diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 440adcf6b9..fdf2141094 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -11,4 +11,5 @@ 12dp 12dp 8dp + 4dp \ No newline at end of file From eab7dd60067ff18bab4a3c2f7d7b6c618bcf2945 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 25 Apr 2018 10:25:34 +0200 Subject: [PATCH 10/36] Fixed procedural shaders --- libraries/render-utils/src/simple.slf | 10 ++++++++++ libraries/render-utils/src/simple_fade.slf | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index ed77777184..338f8607ee 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -16,7 +16,17 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; + +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index 6e7aee2894..1cb4127e7b 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -19,9 +19,19 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; in vec4 _positionWS; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + //PROCEDURAL_COMMON_BLOCK #line 1001 From 328f1dec9be27258b154130f51681ece09b76c97 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 25 Apr 2018 18:56:18 +0200 Subject: [PATCH 11/36] Extended to other shaders --- libraries/render-utils/src/forward_simple.slf | 10 ++++++++++ .../render-utils/src/forward_simple_transparent.slf | 9 +++++++++ libraries/render-utils/src/simple.slf | 8 ++++---- libraries/render-utils/src/simple_fade.slf | 8 ++++---- libraries/render-utils/src/simple_transparent.slf | 10 ++++++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/forward_simple.slf b/libraries/render-utils/src/forward_simple.slf index 587fcbde73..1ac44750a7 100644 --- a/libraries/render-utils/src/forward_simple.slf +++ b/libraries/render-utils/src/forward_simple.slf @@ -16,11 +16,21 @@ <@include ForwardGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> + // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; in vec4 _positionES; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + layout(location = 0) out vec4 _fragColor0; //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/forward_simple_transparent.slf b/libraries/render-utils/src/forward_simple_transparent.slf index f40ba2ed4f..8be2759571 100644 --- a/libraries/render-utils/src/forward_simple_transparent.slf +++ b/libraries/render-utils/src/forward_simple_transparent.slf @@ -18,9 +18,18 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; in vec4 _positionES; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + layout(location = 0) out vec4 _fragColor0; //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 338f8607ee..7591dc1882 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -23,10 +23,10 @@ in vec4 _positionMS; in vec4 _positionES; // For retro-compatibility -#define _normal _normalWS -#define _modelNormal _normalMS -#define _position _positionMS -#define _eyePosition _positionES +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index 1cb4127e7b..0710c3e10b 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -27,10 +27,10 @@ in vec4 _positionES; in vec4 _positionWS; // For retro-compatibility -#define _normal _normalWS -#define _modelNormal _normalMS -#define _position _positionMS -#define _eyePosition _positionES +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_transparent.slf b/libraries/render-utils/src/simple_transparent.slf index c9815e8a80..ee79d2c0c4 100644 --- a/libraries/render-utils/src/simple_transparent.slf +++ b/libraries/render-utils/src/simple_transparent.slf @@ -16,7 +16,17 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; + +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK From 751f8f59d786ca0f63cc9f8138a4c6399ecfbea1 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 25 Apr 2018 20:13:04 -0300 Subject: [PATCH 12/36] Android - Workaround for Joystick disappearing problem in Adreno devices + No excessive rotation in loading moment --- android/app/src/main/AndroidManifest.xml | 2 +- .../io/highfidelity/hifiinterface/InterfaceActivity.java | 3 +++ .../io/highfidelity/hifiinterface/SplashActivity.java | 8 ++++++-- android/app/src/main/res/layout/activity_home.xml | 3 ++- android/app/src/main/res/layout/activity_splash.xml | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8828335cd1..282905a6a8 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -54,7 +54,6 @@ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name=".InterfaceActivity" android:label="@string/app_name" - android:screenOrientation="landscape" android:launchMode="singleTop" > @@ -79,6 +78,7 @@ diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java index 2edab94374..8a2f8cd030 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java @@ -127,6 +127,9 @@ public class InterfaceActivity extends QtActivity { @Override protected void onStart() { super.onStart(); + if (!isLoading) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } // TODO Fix displayPlugin deactivate so it doesn't leave us with a black screen Interface //nativeEnterForeground(); } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index b663a3e396..08f8615a16 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -3,6 +3,7 @@ package io.highfidelity.hifiinterface; import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; public class SplashActivity extends Activity { @@ -26,7 +27,10 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - startActivity(new Intent(this, HomeActivity.class)); - finish(); + // Give interface more time so textures don't fail(got deleted) on Adreno (joystick) + new Handler(getMainLooper()).postDelayed(() -> { + startActivity(new Intent(this, HomeActivity.class)); + new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); + }, 500); } } diff --git a/android/app/src/main/res/layout/activity_home.xml b/android/app/src/main/res/layout/activity_home.xml index c399ac16ec..0269672a29 100644 --- a/android/app/src/main/res/layout/activity_home.xml +++ b/android/app/src/main/res/layout/activity_home.xml @@ -19,7 +19,8 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimaryDark" - android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> + android:elevation="4dp" + /> diff --git a/android/app/src/main/res/layout/activity_splash.xml b/android/app/src/main/res/layout/activity_splash.xml index b38fe3e53c..5b4f91e733 100644 --- a/android/app/src/main/res/layout/activity_splash.xml +++ b/android/app/src/main/res/layout/activity_splash.xml @@ -5,7 +5,7 @@ android:id="@+id/root_activity_splash" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@android:color/transparent"> + android:background="@color/backgroundLight"> From 4954cf83862ae45e064a09be9cc9e4184dbe5b1f Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Thu, 26 Apr 2018 14:59:58 -0300 Subject: [PATCH 13/36] Tweak search domains screen --- .../app/src/main/res/layout/content_home.xml | 20 ++++++++++--------- .../app/src/main/res/layout/domain_view.xml | 12 +++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index 59a7abb66c..ace814909c 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -12,37 +12,39 @@ Date: Thu, 26 Apr 2018 17:10:10 -0300 Subject: [PATCH 14/36] Revert "Merge pull request #12921 from SamGondelman/precisionq" This reverts commit d1e2e9ce71a46abf1aeb89311d0e14a8f2362ed7, reversing changes made to 7842ee8eacbb0574ae63074ac9e00a85840383b1. --- .../gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- .../src/gpu/gl/GLBackendShader.cpp | 21 +++++++++++++++++++ .../gpu-gl/src/gpu/gl41/GL41BackendShader.cpp | 8 +------ .../gpu-gl/src/gpu/gl45/GL45BackendShader.cpp | 16 +++++++------- .../src/gpu/gles/GLESBackendShader.cpp | 11 +--------- libraries/graphics/src/graphics/Light.slh | 9 +++++++- .../src/graphics/LightIrradiance.shared.slh | 8 ++++++- .../src/graphics/LightVolume.shared.slh | 8 +++++++ libraries/graphics/src/graphics/Material.slh | 9 +++++++- .../graphics/SphericalHarmonics.shared.slh | 8 +++++++ libraries/render-utils/src/LightingModel.slh | 8 +++++++ 11 files changed, 78 insertions(+), 30 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 895a7777c9..6355137a19 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -452,7 +452,7 @@ protected: // Backend dependant compilation of the shader virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler); virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler); - virtual std::string getBackendShaderHeader() const = 0; + virtual std::string getBackendShaderHeader() const; virtual void makeProgramBindings(ShaderObject& shaderObject); class ElementResource { public: diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp index bf36c134de..0df228ddc4 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp @@ -12,6 +12,27 @@ using namespace gpu; using namespace gpu::gl; +// GLSL version +std::string GLBackend::getBackendShaderHeader() const { + +#if defined(USE_GLES) + static const std::string header( +R"SHADER(#version 310 es +#extension GL_EXT_texture_buffer : enable +precision lowp float; // check precision 2 +precision lowp samplerBuffer; +precision lowp sampler2DShadow; +)SHADER"); +#else + static const std::string header( +R"SHADER(#version 410 core +)SHADER"); +#endif + + return header; +} + + // Shader domain static const size_t NUM_SHADER_DOMAINS = 3; static_assert(Shader::Type::NUM_DOMAINS == NUM_SHADER_DOMAINS, "GL shader domains must equal defined GPU shader domains"); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp index 151b5bd1f9..35bfafdc50 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp @@ -14,13 +14,7 @@ using namespace gpu::gl41; // GLSL version std::string GL41Backend::getBackendShaderHeader() const { - static const std::string header( - R"SHADER(#version 410 core - #define GPU_GL410 - #define PRECISIONQ - #define BITFIELD int - )SHADER"); - return header; + return std::string("#version 410 core\n#define GPU_GL410 1"); } int GL41Backend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp index 6f6ded518f..8de60a7921 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp @@ -15,17 +15,15 @@ using namespace gpu::gl45; // GLSL version std::string GL45Backend::getBackendShaderHeader() const { - static const std::string header( - R"SHADER(#version 450 core - #define GPU_GL450 - #define PRECISIONQ - #define BITFIELD int - )SHADER" + const char header[] = +R"GLSL(#version 450 core +#define GPU_GL450 +)GLSL" #ifdef GPU_SSBO_TRANSFORM_OBJECT - R"SHADER(#define GPU_SSBO_TRANSFORM_OBJECT)SHADER" + R"GLSL(#define GPU_SSBO_TRANSFORM_OBJECT 1)GLSL" #endif - ); - return header; + ; + return std::string(header); } int GL45Backend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp index 4278d732c8..16cf1559dd 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp @@ -14,16 +14,7 @@ using namespace gpu::gles; // GLSL version std::string GLESBackend::getBackendShaderHeader() const { - static const std::string header( - R"SHADER(#version 310 es - #extension GL_EXT_texture_buffer : enable - precision lowp float; // check precision 2 - precision lowp samplerBuffer; - precision lowp sampler2DShadow; - #define PRECISIONQ highp - #define BITFIELD highp int - )SHADER"); - return header; + return Parent::getBackendShaderHeader(); } int GLESBackend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/graphics/src/graphics/Light.slh b/libraries/graphics/src/graphics/Light.slh index c8992730f0..20394816c9 100644 --- a/libraries/graphics/src/graphics/Light.slh +++ b/libraries/graphics/src/graphics/Light.slh @@ -29,9 +29,16 @@ vec3 getLightColor(Light l) { return lightIrradiance_getColor(l.irradiance); } float getLightIntensity(Light l) { return lightIrradiance_getIntensity(l.irradiance); } vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradiance); } -// Ambient lighting needs extra info provided from a different Buffer +// AMbient lighting needs extra info provided from a different Buffer <@include graphics/SphericalHarmonics.shared.slh@> // Light Ambient +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif struct LightAmbient { PRECISIONQ vec4 _ambient; diff --git a/libraries/graphics/src/graphics/LightIrradiance.shared.slh b/libraries/graphics/src/graphics/LightIrradiance.shared.slh index 4ae7967bf5..ff42f57fd9 100644 --- a/libraries/graphics/src/graphics/LightIrradiance.shared.slh +++ b/libraries/graphics/src/graphics/LightIrradiance.shared.slh @@ -12,7 +12,13 @@ #define LightIrradianceConstRef LightIrradiance - +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif struct LightIrradiance { PRECISIONQ vec4 colorIntensity; // falloffRadius, cutoffRadius, falloffSpot, spare diff --git a/libraries/graphics/src/graphics/LightVolume.shared.slh b/libraries/graphics/src/graphics/LightVolume.shared.slh index 4e4359eac0..48249e766f 100644 --- a/libraries/graphics/src/graphics/LightVolume.shared.slh +++ b/libraries/graphics/src/graphics/LightVolume.shared.slh @@ -15,6 +15,14 @@ #define LightVolumeConstRef LightVolume +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif + struct LightVolume { PRECISIONQ vec4 positionRadius; PRECISIONQ vec4 directionSpotCos; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index ecf3c18a0e..f9f4144748 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -13,7 +13,14 @@ // The material values (at least the material key) must be precisely bitwise accurate // to what is provided by the uniform buffer, or the material key has the wrong bits - +#ifdef GL_ES +precision highp float; +#define BITFIELD highp int +#define PRECISIONQ highp +#else +#define BITFIELD int +#define PRECISIONQ +#endif struct Material { PRECISIONQ vec4 _emissiveOpacity; PRECISIONQ vec4 _albedoRoughness; diff --git a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh index 6e1763dcba..72a505fa25 100644 --- a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh +++ b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh @@ -15,6 +15,14 @@ #define SphericalHarmonicsConstRef SphericalHarmonics +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif + struct SphericalHarmonics { PRECISIONQ vec4 L00; PRECISIONQ vec4 L1m1; diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index 6a5982f1e8..3f615f11db 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -13,6 +13,14 @@ <@func declareLightingModel()@> +#ifndef PRECISIONQ +#ifdef GL_ES +#define PRECISIONQ highp +#else +#define PRECISIONQ +#endif +#endif + struct LightingModel { PRECISIONQ vec4 _UnlitEmissiveLightmapBackground; PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo; From fdc9df73c2499826e93793853db453d1b00903d0 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Thu, 26 Apr 2018 21:44:58 -0300 Subject: [PATCH 15/36] Android - Search - Dimensions fixes --- .../hifiinterface/HomeActivity.java | 7 ++++++ .../app/src/main/res/layout/content_home.xml | 22 +++++++++---------- .../app/src/main/res/layout/domain_view.xml | 12 +++++----- android/app/src/main/res/values/colors.xml | 1 + android/app/src/main/res/values/dimens.xml | 21 ++++++++++++++++++ android/app/src/main/res/values/styles.xml | 2 +- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 4227de4ac9..71035bfbef 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.NavigationView; +import android.support.v4.content.ContextCompat; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; @@ -17,6 +18,8 @@ import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; @@ -134,6 +137,10 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On updateLoginMenu(); + Window window = getWindow(); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(ContextCompat.getColor(this, R.color.statusbar_color)); } private void updateLoginMenu() { diff --git a/android/app/src/main/res/layout/content_home.xml b/android/app/src/main/res/layout/content_home.xml index ace814909c..5b58100a14 100644 --- a/android/app/src/main/res/layout/content_home.xml +++ b/android/app/src/main/res/layout/content_home.xml @@ -12,39 +12,39 @@ #F2F2F2 #FF7171 #99000000 + #292929 diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index fdf2141094..b2eaea5ee7 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -12,4 +12,25 @@ 12dp 8dp 4dp + + + 47.5dp + 11dp + 24dp + 51dp + 19sp + 16dp + 16dp + 22dp + 16dp + 16dp + 22dp + + 163dp + 14dp + 14dp + 2dp + 6dp + 64dp + \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 5b32de2465..308c438fa6 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -42,7 +42,7 @@ From 8e0886667ece0de23df0f52391cb1e011b631c4f Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 27 Apr 2018 16:54:45 -0300 Subject: [PATCH 16/36] Revert "Revert "Merge pull request #12921 from SamGondelman/precisionq"" This reverts commit 729e9c21620a86e604b0b1b376691dec84f2f607. --- .../gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- .../src/gpu/gl/GLBackendShader.cpp | 21 ------------------- .../gpu-gl/src/gpu/gl41/GL41BackendShader.cpp | 8 ++++++- .../gpu-gl/src/gpu/gl45/GL45BackendShader.cpp | 16 +++++++------- .../src/gpu/gles/GLESBackendShader.cpp | 11 +++++++++- libraries/graphics/src/graphics/Light.slh | 9 +------- .../src/graphics/LightIrradiance.shared.slh | 8 +------ .../src/graphics/LightVolume.shared.slh | 8 ------- libraries/graphics/src/graphics/Material.slh | 9 +------- .../graphics/SphericalHarmonics.shared.slh | 8 ------- libraries/render-utils/src/LightingModel.slh | 8 ------- 11 files changed, 30 insertions(+), 78 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 6355137a19..895a7777c9 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -452,7 +452,7 @@ protected: // Backend dependant compilation of the shader virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler); virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler); - virtual std::string getBackendShaderHeader() const; + virtual std::string getBackendShaderHeader() const = 0; virtual void makeProgramBindings(ShaderObject& shaderObject); class ElementResource { public: diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp index 0df228ddc4..bf36c134de 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp @@ -12,27 +12,6 @@ using namespace gpu; using namespace gpu::gl; -// GLSL version -std::string GLBackend::getBackendShaderHeader() const { - -#if defined(USE_GLES) - static const std::string header( -R"SHADER(#version 310 es -#extension GL_EXT_texture_buffer : enable -precision lowp float; // check precision 2 -precision lowp samplerBuffer; -precision lowp sampler2DShadow; -)SHADER"); -#else - static const std::string header( -R"SHADER(#version 410 core -)SHADER"); -#endif - - return header; -} - - // Shader domain static const size_t NUM_SHADER_DOMAINS = 3; static_assert(Shader::Type::NUM_DOMAINS == NUM_SHADER_DOMAINS, "GL shader domains must equal defined GPU shader domains"); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp index 35bfafdc50..151b5bd1f9 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp @@ -14,7 +14,13 @@ using namespace gpu::gl41; // GLSL version std::string GL41Backend::getBackendShaderHeader() const { - return std::string("#version 410 core\n#define GPU_GL410 1"); + static const std::string header( + R"SHADER(#version 410 core + #define GPU_GL410 + #define PRECISIONQ + #define BITFIELD int + )SHADER"); + return header; } int GL41Backend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp index 8de60a7921..6f6ded518f 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp @@ -15,15 +15,17 @@ using namespace gpu::gl45; // GLSL version std::string GL45Backend::getBackendShaderHeader() const { - const char header[] = -R"GLSL(#version 450 core -#define GPU_GL450 -)GLSL" + static const std::string header( + R"SHADER(#version 450 core + #define GPU_GL450 + #define PRECISIONQ + #define BITFIELD int + )SHADER" #ifdef GPU_SSBO_TRANSFORM_OBJECT - R"GLSL(#define GPU_SSBO_TRANSFORM_OBJECT 1)GLSL" + R"SHADER(#define GPU_SSBO_TRANSFORM_OBJECT)SHADER" #endif - ; - return std::string(header); + ); + return header; } int GL45Backend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp index 16cf1559dd..4278d732c8 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp @@ -14,7 +14,16 @@ using namespace gpu::gles; // GLSL version std::string GLESBackend::getBackendShaderHeader() const { - return Parent::getBackendShaderHeader(); + static const std::string header( + R"SHADER(#version 310 es + #extension GL_EXT_texture_buffer : enable + precision lowp float; // check precision 2 + precision lowp samplerBuffer; + precision lowp sampler2DShadow; + #define PRECISIONQ highp + #define BITFIELD highp int + )SHADER"); + return header; } int GLESBackend::makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) { diff --git a/libraries/graphics/src/graphics/Light.slh b/libraries/graphics/src/graphics/Light.slh index 20394816c9..c8992730f0 100644 --- a/libraries/graphics/src/graphics/Light.slh +++ b/libraries/graphics/src/graphics/Light.slh @@ -29,16 +29,9 @@ vec3 getLightColor(Light l) { return lightIrradiance_getColor(l.irradiance); } float getLightIntensity(Light l) { return lightIrradiance_getIntensity(l.irradiance); } vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradiance); } -// AMbient lighting needs extra info provided from a different Buffer +// Ambient lighting needs extra info provided from a different Buffer <@include graphics/SphericalHarmonics.shared.slh@> // Light Ambient -#ifndef PRECISIONQ -#ifdef GL_ES -#define PRECISIONQ highp -#else -#define PRECISIONQ -#endif -#endif struct LightAmbient { PRECISIONQ vec4 _ambient; diff --git a/libraries/graphics/src/graphics/LightIrradiance.shared.slh b/libraries/graphics/src/graphics/LightIrradiance.shared.slh index ff42f57fd9..4ae7967bf5 100644 --- a/libraries/graphics/src/graphics/LightIrradiance.shared.slh +++ b/libraries/graphics/src/graphics/LightIrradiance.shared.slh @@ -12,13 +12,7 @@ #define LightIrradianceConstRef LightIrradiance -#ifndef PRECISIONQ -#ifdef GL_ES -#define PRECISIONQ highp -#else -#define PRECISIONQ -#endif -#endif + struct LightIrradiance { PRECISIONQ vec4 colorIntensity; // falloffRadius, cutoffRadius, falloffSpot, spare diff --git a/libraries/graphics/src/graphics/LightVolume.shared.slh b/libraries/graphics/src/graphics/LightVolume.shared.slh index 48249e766f..4e4359eac0 100644 --- a/libraries/graphics/src/graphics/LightVolume.shared.slh +++ b/libraries/graphics/src/graphics/LightVolume.shared.slh @@ -15,14 +15,6 @@ #define LightVolumeConstRef LightVolume -#ifndef PRECISIONQ -#ifdef GL_ES -#define PRECISIONQ highp -#else -#define PRECISIONQ -#endif -#endif - struct LightVolume { PRECISIONQ vec4 positionRadius; PRECISIONQ vec4 directionSpotCos; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index f9f4144748..ecf3c18a0e 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -13,14 +13,7 @@ // The material values (at least the material key) must be precisely bitwise accurate // to what is provided by the uniform buffer, or the material key has the wrong bits -#ifdef GL_ES -precision highp float; -#define BITFIELD highp int -#define PRECISIONQ highp -#else -#define BITFIELD int -#define PRECISIONQ -#endif + struct Material { PRECISIONQ vec4 _emissiveOpacity; PRECISIONQ vec4 _albedoRoughness; diff --git a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh index 72a505fa25..6e1763dcba 100644 --- a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh +++ b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh @@ -15,14 +15,6 @@ #define SphericalHarmonicsConstRef SphericalHarmonics -#ifndef PRECISIONQ -#ifdef GL_ES -#define PRECISIONQ highp -#else -#define PRECISIONQ -#endif -#endif - struct SphericalHarmonics { PRECISIONQ vec4 L00; PRECISIONQ vec4 L1m1; diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index 3f615f11db..6a5982f1e8 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -13,14 +13,6 @@ <@func declareLightingModel()@> -#ifndef PRECISIONQ -#ifdef GL_ES -#define PRECISIONQ highp -#else -#define PRECISIONQ -#endif -#endif - struct LightingModel { PRECISIONQ vec4 _UnlitEmissiveLightmapBackground; PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo; From e47173a3d921c93f9298eea1ec1f38e63f3ef2aa Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 27 Apr 2018 17:14:48 -0300 Subject: [PATCH 17/36] Set highp float precision for material values --- libraries/graphics/src/graphics/Material.slh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index ecf3c18a0e..76ce336406 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -13,6 +13,9 @@ // The material values (at least the material key) must be precisely bitwise accurate // to what is provided by the uniform buffer, or the material key has the wrong bits +#ifdef GL_ES +precision highp float; +#endif struct Material { PRECISIONQ vec4 _emissiveOpacity; From 3601a2e2b5d812a5154319b23e84bc06012a2df7 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 30 Apr 2018 18:11:23 -0300 Subject: [PATCH 18/36] Android Search - No keyboard popup when starting + search hint no clip on the right --- .../main/java/io/highfidelity/hifiinterface/HomeActivity.java | 2 ++ android/app/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 71035bfbef..2522e3a5eb 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -135,6 +135,8 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On return false; }); + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + updateLoginMenu(); Window window = getWindow(); diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 2cd8944b6f..cc06c12350 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -20,7 +20,7 @@ Forgot password? Username or password incorrect. Logging into High Fidelity - Search for a place by name + Search for a place by name\u00A0 Loading places… No places exist with that name From afc929b07a132b0c12fd17b54ab91c51a251467f Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 2 May 2018 16:31:45 -0300 Subject: [PATCH 19/36] Android - Make ripple effect visible by adding a delay --- .../java/io/highfidelity/hifiinterface/HomeActivity.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 2522e3a5eb..759665b660 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -2,6 +2,7 @@ package io.highfidelity.hifiinterface; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.support.annotation.NonNull; import android.support.design.widget.NavigationView; import android.support.v4.content.ContextCompat; @@ -76,7 +77,12 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On @Override public void onItemClick(View view, int position, DomainAdapter.Domain domain) { - gotoDomain(domain.url); + new Handler(getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + gotoDomain(domain.url); + } + }, 400); // a delay so the ripple effect can be seen } }); mDomainAdapter.setListener(new DomainAdapter.AdapterListener() { From 79576e0f48f9dd7b080d333d9d4b5113853e89e7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 3 May 2018 17:16:35 -0700 Subject: [PATCH 20/36] update request and dependency hoek for CVE --- server-console/package-lock.json | 355 +++++++++++++------------------ server-console/package.json | 2 +- 2 files changed, 147 insertions(+), 210 deletions(-) diff --git a/server-console/package-lock.json b/server-console/package-lock.json index 4311fde51a..4f12f2fa00 100644 --- a/server-console/package-lock.json +++ b/server-console/package-lock.json @@ -20,7 +20,6 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, "requires": { "co": "4.6.0", "fast-deep-equal": "1.0.0", @@ -41,11 +40,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, "array-find-index": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz", @@ -118,16 +112,10 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "author-regex": { "version": "1.0.0", @@ -136,17 +124,14 @@ "dev": true }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.3.2.tgz", - "integrity": "sha1-054L7kEs7Q6O2Uoj4xTzE6lbn9E=", - "requires": { - "lru-cache": "4.0.1" - } + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" }, "base64-js": { "version": "1.2.0", @@ -204,11 +189,11 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.1" } }, "buffers": { @@ -239,9 +224,9 @@ } }, "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chainsaw": { "version": "0.1.0", @@ -252,18 +237,6 @@ "traverse": "0.3.9" } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, "cheerio": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", @@ -295,8 +268,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "code-point-at": { "version": "1.0.0", @@ -318,6 +290,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, "requires": { "graceful-readlink": "1.0.1" } @@ -373,11 +346,21 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "2.10.1" + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.1" + } + } } }, "css-select": { @@ -728,7 +711,7 @@ "minimist": "1.2.0", "pretty-bytes": "1.0.4", "progress-stream": "1.2.0", - "request": "2.71.0", + "request": "2.85.0", "single-line-log": "1.1.2", "throttleit": "0.0.2" }, @@ -828,11 +811,6 @@ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "extend": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", @@ -875,14 +853,12 @@ "fast-deep-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fd-slicer": { "version": "1.0.1", @@ -976,13 +952,23 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "1.0.0-rc4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", - "integrity": "sha1-BaxrwiIntD5EYfSIFhVUaZ1Pi14=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "async": "1.5.2", - "combined-stream": "1.0.5", - "mime-types": "2.1.10" + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "1.0.0" + } + } } }, "fs-extra": { @@ -1058,19 +1044,6 @@ } } }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "requires": { - "is-property": "1.0.2" - } - }, "get-package-info": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", @@ -1212,7 +1185,8 @@ "graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true }, "growly": { "version": "1.3.0", @@ -1222,43 +1196,32 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "chalk": "1.1.3", - "commander": "2.9.0", - "is-my-json-valid": "2.13.1", - "pinkie-promise": "2.0.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" }, "home-path": { "version": "1.0.5", @@ -1301,13 +1264,20 @@ } }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "0.2.0", + "assert-plus": "1.0.0", "jsprim": "1.2.2", "sshpk": "1.7.4" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } } }, "indent-string": { @@ -1388,28 +1358,12 @@ "number-is-nan": "1.0.0" } }, - "is-my-json-valid": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz", - "integrity": "sha1-1Vd4qC/rawlj/0vhEdXRaE6JBwc=", - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "2.0.0", - "xtend": "4.0.1" - } - }, "is-promise": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", "dev": true }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1465,8 +1419,7 @@ "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, "json-stringify-safe": { "version": "5.0.1", @@ -1478,11 +1431,6 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.2.3.tgz", "integrity": "sha1-4lK5mmr5AdPsQfMyWJyQUJp7xgU=" }, - "jsonpointer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz", - "integrity": "sha1-OvHdIP6FRjkQ1GmjheMwF9KgMNk=" - }, "jsprim": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.2.2.tgz", @@ -1569,15 +1517,6 @@ "signal-exit": "2.1.2" } }, - "lru-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", - "integrity": "sha1-E0OVXtry432bnn7nJB4nxLn7cr4=", - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.0.0" - } - }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", @@ -1603,16 +1542,16 @@ } }, "mime-db": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.22.0.tgz", - "integrity": "sha1-qyOmNy3J2G09yRIb0OvTgQWhkEo=" + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.10.tgz", - "integrity": "sha1-uTx8tDYuFtQQcqflRTj7TUMHCDc=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "requires": { - "mime-db": "1.22.0" + "mime-db": "1.33.0" } }, "minimist": { @@ -1891,11 +1830,6 @@ } } }, - "node-uuid": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", - "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" - }, "nodeify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz", @@ -1945,7 +1879,7 @@ "minimist": "1.2.0", "pretty-bytes": "1.0.4", "progress-stream": "1.2.0", - "request": "2.71.0", + "request": "2.85.0", "single-line-log": "1.1.2", "throttleit": "0.0.2" }, @@ -1973,9 +1907,9 @@ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=" }, "oauth-sign": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.1.tgz", - "integrity": "sha1-GCQ5vbkTeL90YOdcZOpD5kSN7wY=" + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, "object-assign": { "version": "4.0.1", @@ -2099,8 +2033,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "2.3.0", @@ -2111,12 +2044,14 @@ "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, "requires": { "pinkie": "2.0.4" } @@ -2166,11 +2101,6 @@ "is-promise": "1.0.1" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "pump": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.1.tgz", @@ -2183,8 +2113,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "q": { "version": "1.5.1", @@ -2193,9 +2122,9 @@ "dev": true }, "qs": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.1.0.tgz", - "integrity": "sha1-7B0WJrJCeNmfD99FSeUk4k7O6yY=" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "rc": { "version": "1.1.6", @@ -2252,31 +2181,39 @@ } }, "request": { - "version": "2.71.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.71.0.tgz", - "integrity": "sha1-bxRkPJxaZ8ruapXPjvBHfVYDvZE=", + "version": "2.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.3.2", - "bl": "1.1.2", - "caseless": "0.11.0", + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", "combined-stream": "1.0.5", - "extend": "3.0.0", + "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "1.0.0-rc4", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.10", - "node-uuid": "1.4.7", - "oauth-sign": "0.8.1", - "qs": "6.1.0", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.2.2", - "tunnel-agent": "0.4.2" + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + }, + "dependencies": { + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + } } }, "request-progress": { @@ -2308,8 +2245,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "sanitize-filename": { "version": "1.6.1", @@ -2347,11 +2283,11 @@ } }, "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.1" } }, "spdx-correct": { @@ -2483,11 +2419,6 @@ } } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, "tar-fs": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.12.0.tgz", @@ -2585,9 +2516,12 @@ } }, "tough-cookie": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=" + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "1.4.1" + } }, "traverse": { "version": "0.3.9", @@ -2611,9 +2545,12 @@ } }, "tunnel-agent": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.2.tgz", - "integrity": "sha1-EQTj82rIcSXChycAZ9WC0YEzv+4=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } }, "tweetnacl": { "version": "0.14.3", @@ -2644,6 +2581,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -2710,11 +2652,6 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, - "yallist": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", - "integrity": "sha1-MGxUODXwnuGkyyO3vOmrNByRzdQ=" - }, "yargs": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", diff --git a/server-console/package.json b/server-console/package.json index 2428d2574e..6dd39ea6f8 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -30,7 +30,7 @@ "fs-extra": "^1.0.0", "node-notifier": "^5.2.1", "os-homedir": "^1.0.1", - "request": "^2.67.0", + "request": "^2.85.0", "request-progress": "1.0.2", "tar-fs": "^1.12.0", "yargs": "^3.30.0" From d774dc2060e546612526cf7df7877ee39ad87812 Mon Sep 17 00:00:00 2001 From: Clement Date: Thu, 26 Apr 2018 18:34:38 -0700 Subject: [PATCH 21/36] WIP Only use conical frustums on the server --- .../src/entities/EntityPriorityQueue.cpp | 76 -------- .../src/entities/EntityTreeSendThread.cpp | 87 ++------- .../src/entities/EntityTreeSendThread.h | 4 +- libraries/entities/src/DiffTraversal.cpp | 179 ++++++++---------- libraries/entities/src/DiffTraversal.h | 14 +- .../entities/src}/EntityPriorityQueue.h | 38 +--- libraries/shared/src/GLMHelpers.cpp | 6 + libraries/shared/src/GLMHelpers.h | 2 + libraries/shared/src/ViewFrustum.cpp | 7 - .../shared/src/shared/ConicalViewFrustum.cpp | 125 ++++++++++++ .../shared/src/shared/ConicalViewFrustum.h | 64 +++++++ 11 files changed, 306 insertions(+), 296 deletions(-) delete mode 100644 assignment-client/src/entities/EntityPriorityQueue.cpp rename {assignment-client/src/entities => libraries/entities/src}/EntityPriorityQueue.h (70%) create mode 100644 libraries/shared/src/shared/ConicalViewFrustum.cpp create mode 100644 libraries/shared/src/shared/ConicalViewFrustum.h diff --git a/assignment-client/src/entities/EntityPriorityQueue.cpp b/assignment-client/src/entities/EntityPriorityQueue.cpp deleted file mode 100644 index 88dee58f9d..0000000000 --- a/assignment-client/src/entities/EntityPriorityQueue.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// -// EntityPriorityQueue.cpp -// assignment-client/src/entities -// -// Created by Andrew Meadows 2017.08.08 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "EntityPriorityQueue.h" - -const float PrioritizedEntity::DO_NOT_SEND = -1.0e-6f; -const float PrioritizedEntity::FORCE_REMOVE = -1.0e-5f; -const float PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY = 1.0f; - -void ConicalViewFrustum::set(const ViewFrustum& viewFrustum) { - // The ConicalView has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part. - // Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum. - _position = viewFrustum.getPosition(); - _direction = viewFrustum.getDirection(); - - // We cache the sin and cos of the half angle of the cone that bounds the frustum. - // (the math here is left as an exercise for the reader) - float A = viewFrustum.getAspectRatio(); - float t = tanf(0.5f * viewFrustum.getFieldOfView()); - _cosAngle = 1.0f / sqrtf(1.0f + (A * A + 1.0f) * (t * t)); - _sinAngle = sqrtf(1.0f - _cosAngle * _cosAngle); - - _radius = viewFrustum.getCenterRadius(); -} - -float ConicalViewFrustum::computePriority(const AACube& cube) const { - glm::vec3 p = cube.calcCenter() - _position; // position of bounding sphere in view-frame - float d = glm::length(p); // distance to center of bounding sphere - float r = 0.5f * cube.getScale(); // radius of bounding sphere - if (d < _radius + r) { - return r; - } - // We check the angle between the center of the cube and the _direction of the view. - // If it is less than the sum of the half-angle from center of cone to outer edge plus - // the half apparent angle of the bounding sphere then it is in view. - // - // The math here is left as an exercise for the reader with the following hints: - // (1) We actually check the dot product of the cube's local position rather than the angle and - // (2) we take advantage of this trig identity: cos(A+B) = cos(A)*cos(B) - sin(A)*sin(B) - if (glm::dot(p, _direction) > sqrtf(d * d - r * r) * _cosAngle - r * _sinAngle) { - const float AVOID_DIVIDE_BY_ZERO = 0.001f; - return r / (d + AVOID_DIVIDE_BY_ZERO); - } - return PrioritizedEntity::DO_NOT_SEND; -} - - -void ConicalView::set(const DiffTraversal::View& view) { - auto size = view.viewFrustums.size(); - _conicalViewFrustums.resize(size); - for (size_t i = 0; i < size; ++i) { - _conicalViewFrustums[i].set(view.viewFrustums[i]); - } -} - -float ConicalView::computePriority(const AACube& cube) const { - if (_conicalViewFrustums.empty()) { - return PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; - } - - float priority = PrioritizedEntity::DO_NOT_SEND; - - for (const auto& view : _conicalViewFrustums) { - priority = std::max(priority, view.computePriority(cube)); - } - - return priority; -} diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 2e57f2e00f..0d943055f4 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -141,16 +141,8 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O if (forceRemove) { priority = PrioritizedEntity::FORCE_REMOVE; } else { - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - const auto& view = _traversal.getCurrentView(); - if (view.intersects(cube) && view.isBigEnough(cube)) { - priority = _conicalView.computePriority(cube); - } - } else { - priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; - } + const auto& view = _traversal.getCurrentView(); + priority = view.computePriority(entity); } if (priority != PrioritizedEntity::DO_NOT_SEND) { @@ -235,11 +227,6 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En // (3) Differential = view has changed --> find what has changed or in new view but not old // // The "scanCallback" we provide to the traversal depends on the type: - // - // The _conicalView is updated here as a cached view approximation used by the lambdas for efficient - // computation of entity sorting priorities. - // - _conicalView.set(_traversal.getCurrentView()); switch (type) { case DiffTraversal::First: @@ -251,25 +238,8 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En if (_sendQueue.contains(entity.get())) { return; } - float priority = PrioritizedEntity::DO_NOT_SEND; - - - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - const auto& view = _traversal.getCurrentView(); - // Check the size of the entity, it's possible that a "too small to see" entity is included in a - // larger octree cell because of its position (for example if it crosses the boundary of a cell it - // pops to the next higher cell. So we want to check to see that the entity is large enough to be seen - // before we consider including it. - if ((next.intersection == ViewFrustum::INSIDE || view.intersects(cube)) && - view.isBigEnough(cube)) { - priority = _conicalView.computePriority(cube); - } - } else { - priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; - } - + const auto& view = _traversal.getCurrentView(); + float priority = view.computePriority(entity); if (priority != PrioritizedEntity::DO_NOT_SEND) { _sendQueue.emplace(entity, priority); @@ -288,21 +258,11 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En } float priority = PrioritizedEntity::DO_NOT_SEND; - auto knownTimestamp = _knownState.find(entity.get()); if (knownTimestamp == _knownState.end()) { - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - const auto& view = _traversal.getCurrentView(); - // See the DiffTraversal::First case for an explanation of the "entity is too small" check - if ((next.intersection == ViewFrustum::INSIDE || view.intersects(cube)) && - view.isBigEnough(cube)) { - priority = _conicalView.computePriority(cube); - } - } else { - priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; - } + const auto& view = _traversal.getCurrentView(); + priority = view.computePriority(entity); + } else if (entity->getLastEdited() > knownTimestamp->second || entity->getLastChangedOnServer() > knownTimestamp->second) { // it is known and it changed --> put it on the queue with any priority @@ -310,7 +270,6 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; } - if (priority != PrioritizedEntity::DO_NOT_SEND) { _sendQueue.emplace(entity, priority); } @@ -328,21 +287,11 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En } float priority = PrioritizedEntity::DO_NOT_SEND; - auto knownTimestamp = _knownState.find(entity.get()); if (knownTimestamp == _knownState.end()) { - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - const auto& view = _traversal.getCurrentView(); - // See the DiffTraversal::First case for an explanation of the "entity is too small" check - if ((next.intersection == ViewFrustum::INSIDE || view.intersects(cube)) && - view.isBigEnough(cube)) { - priority = _conicalView.computePriority(cube); - } - } else { - priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; - } + const auto& view = _traversal.getCurrentView(); + priority = view.computePriority(entity); + } else if (entity->getLastEdited() > knownTimestamp->second || entity->getLastChangedOnServer() > knownTimestamp->second) { // it is known and it changed --> put it on the queue with any priority @@ -350,7 +299,6 @@ void EntityTreeSendThread::startNewTraversal(const DiffTraversal::View& view, En priority = PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; } - if (priority != PrioritizedEntity::DO_NOT_SEND) { _sendQueue.emplace(entity, priority); } @@ -463,14 +411,13 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream void EntityTreeSendThread::editingEntityPointer(const EntityItemPointer& entity) { if (entity) { if (!_sendQueue.contains(entity.get()) && _knownState.find(entity.get()) != _knownState.end()) { - bool success = false; - AACube cube = entity->getQueryAACube(success); - if (success) { - // We can force a removal from _knownState if the current view is used and entity is out of view - if (_traversal.doesCurrentUseViewFrustum() && !_traversal.getCurrentView().intersects(cube)) { - _sendQueue.emplace(entity, PrioritizedEntity::FORCE_REMOVE, true); - } - } else { + const auto& view = _traversal.getCurrentView(); + float priority = view.computePriority(entity); + + // We can force a removal from _knownState if the current view is used and entity is out of view + if (priority == PrioritizedEntity::DO_NOT_SEND) { + _sendQueue.emplace(entity, PrioritizedEntity::FORCE_REMOVE, true); + } else if (priority == PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY) { _sendQueue.emplace(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY, true); } } diff --git a/assignment-client/src/entities/EntityTreeSendThread.h b/assignment-client/src/entities/EntityTreeSendThread.h index 9eea98b7fd..1305d7bfc7 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.h +++ b/assignment-client/src/entities/EntityTreeSendThread.h @@ -17,8 +17,9 @@ #include "../octree/OctreeSendThread.h" #include +#include +#include -#include "EntityPriorityQueue.h" class EntityNodeData; class EntityItem; @@ -51,7 +52,6 @@ private: DiffTraversal _traversal; EntityPriorityQueue _sendQueue; std::unordered_map _knownState; - ConicalView _conicalView; // cached optimized view for fast priority calculations // packet construction stuff EntityTreeElementExtraEncodeDataPointer _extraEncodeData { new EntityTreeElementExtraEncodeData() }; diff --git a/libraries/entities/src/DiffTraversal.cpp b/libraries/entities/src/DiffTraversal.cpp index 39328e11ad..36d1f41267 100644 --- a/libraries/entities/src/DiffTraversal.cpp +++ b/libraries/entities/src/DiffTraversal.cpp @@ -13,6 +13,8 @@ #include +#include "EntityPriorityQueue.h" + DiffTraversal::Waypoint::Waypoint(EntityTreeElementPointer& element) : _nextIndex(0) { assert(element); _weakElement = element; @@ -35,19 +37,9 @@ void DiffTraversal::Waypoint::getNextVisibleElementFirstTime(DiffTraversal::Visi while (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer nextElement = element->getChildAtIndex(_nextIndex); ++_nextIndex; - if (nextElement) { - const auto& cube = nextElement->getAACube(); - if (!view.usesViewFrustums()) { - // No LOD truncation if we aren't using the view frustum - next.element = nextElement; - return; - } else if (view.intersects(cube)) { - // check for LOD truncation - if (view.isBigEnough(cube, MIN_ELEMENT_ANGULAR_DIAMETER)) { - next.element = nextElement; - return; - } - } + if (nextElement && view.shouldTraverseElement(*nextElement)) { + next.element = nextElement; + return; } } } @@ -63,7 +55,6 @@ void DiffTraversal::Waypoint::getNextVisibleElementRepeat( EntityTreeElementPointer element = _weakElement.lock(); if (element->getLastChangedContent() > lastTime) { next.element = element; - next.intersection = ViewFrustum::INTERSECT; return; } } @@ -73,30 +64,17 @@ void DiffTraversal::Waypoint::getNextVisibleElementRepeat( while (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer nextElement = element->getChildAtIndex(_nextIndex); ++_nextIndex; - if (nextElement && nextElement->getLastChanged() > lastTime) { - if (!view.usesViewFrustums()) { - // No LOD truncation if we aren't using the view frustum - next.element = nextElement; - next.intersection = ViewFrustum::INSIDE; - return; - } else { - // check for LOD truncation - const auto& cube = nextElement->getAACube(); - if (view.isBigEnough(cube, MIN_ELEMENT_ANGULAR_DIAMETER)) { - ViewFrustum::intersection intersection = view.calculateIntersection(cube); - if (intersection != ViewFrustum::OUTSIDE) { - next.element = nextElement; - next.intersection = intersection; - return; - } - } - } + if (nextElement && + nextElement->getLastChanged() > lastTime && + view.shouldTraverseElement(*nextElement)) { + + next.element = nextElement; + return; } } } } next.element.reset(); - next.intersection = ViewFrustum::OUTSIDE; } void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::VisibleElement& next, @@ -106,7 +84,6 @@ void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::V ++_nextIndex; EntityTreeElementPointer element = _weakElement.lock(); next.element = element; - next.intersection = ViewFrustum::INTERSECT; return; } else if (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer element = _weakElement.lock(); @@ -114,74 +91,14 @@ void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::V while (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer nextElement = element->getChildAtIndex(_nextIndex); ++_nextIndex; - if (nextElement) { - // check for LOD truncation - const auto& cube = nextElement->getAACube(); - if (view.isBigEnough(cube, MIN_ELEMENT_ANGULAR_DIAMETER)) { - ViewFrustum::intersection intersection = view.calculateIntersection(cube); - if (intersection != ViewFrustum::OUTSIDE) { - next.element = nextElement; - next.intersection = intersection; - return; - } - } + if (nextElement && view.shouldTraverseElement(*nextElement)) { + next.element = nextElement; + return; } } } } next.element.reset(); - next.intersection = ViewFrustum::OUTSIDE; -} - -bool DiffTraversal::View::isBigEnough(const AACube& cube, float minDiameter) const { - if (viewFrustums.empty()) { - // Everything is big enough when not using view frustums - return true; - } - - bool isBigEnough = std::any_of(std::begin(viewFrustums), std::end(viewFrustums), - [&](const ViewFrustum& viewFrustum) { - return isAngularSizeBigEnough(viewFrustum.getPosition(), cube, lodScaleFactor, minDiameter); - }); - - return isBigEnough; -} - -bool DiffTraversal::View::intersects(const AACube& cube) const { - if (viewFrustums.empty()) { - // Everything intersects when not using view frustums - return true; - } - - bool intersects = std::any_of(std::begin(viewFrustums), std::end(viewFrustums), - [&](const ViewFrustum& viewFrustum) { - return viewFrustum.cubeIntersectsKeyhole(cube); - }); - - return intersects; -} - -ViewFrustum::intersection DiffTraversal::View::calculateIntersection(const AACube& cube) const { - if (viewFrustums.empty()) { - // Everything is inside when not using view frustums - return ViewFrustum::INSIDE; - } - - ViewFrustum::intersection intersection = ViewFrustum::OUTSIDE; - - for (const auto& viewFrustum : viewFrustums) { - switch (viewFrustum.calculateCubeKeyholeIntersection(cube)) { - case ViewFrustum::INSIDE: - return ViewFrustum::INSIDE; - case ViewFrustum::INTERSECT: - intersection = ViewFrustum::INTERSECT; - break; - default: - // DO NOTHING - break; - } - } - return intersection; } bool DiffTraversal::View::usesViewFrustums() const { @@ -204,6 +121,73 @@ bool DiffTraversal::View::isVerySimilar(const View& view) const { return true; } +float DiffTraversal::View::computePriority(const EntityItemPointer& entity) const { + if (!entity) { + return PrioritizedEntity::DO_NOT_SEND; + } + + if (!usesViewFrustums()) { + return PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; + } + + bool success = false; + auto cube = entity->getQueryAACube(success); + if (!success) { + return PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY; + } + + auto center = cube.calcCenter(); // center of bounding sphere + auto radius = 0.5f * SQRT_THREE * cube.getScale(); // radius of bounding sphere + + auto priority = PrioritizedEntity::DO_NOT_SEND; + + for (const auto& frustum : viewFrustums) { + auto position = center - frustum.getPosition(); // position of bounding sphere in view-frame + float distance = glm::length(position); // distance to center of bounding sphere + + // Check the size of the entity, it's possible that a "too small to see" entity is included in a + // larger octree cell because of its position (for example if it crosses the boundary of a cell it + // pops to the next higher cell. So we want to check to see that the entity is large enough to be seen + // before we consider including it. + float angularSize = frustum.getAngularSize(distance, radius); + if (angularSize > lodScaleFactor * MIN_ENTITY_ANGULAR_DIAMETER && + frustum.intersects(position, distance, radius)) { + + // use the angular size as priority + // we compute the max priority for all frustums + priority = std::max(priority, angularSize); + } + } + + return priority; +} + +bool DiffTraversal::View::shouldTraverseElement(const EntityTreeElement& element) const { + if (!usesViewFrustums()) { + return true; + } + + const auto& cube = element.getAACube(); + + auto center = cube.calcCenter(); // center of bounding sphere + auto radius = 0.5f * SQRT_THREE * cube.getScale(); // radius of bounding sphere + + + return any_of(begin(viewFrustums), end(viewFrustums), [&](const ConicalViewFrustum& frustum) { + auto position = center - frustum.getPosition(); // position of bounding sphere in view-frame + float distance = glm::length(position); // distance to center of bounding sphere + + // Check the size of the entity, it's possible that a "too small to see" entity is included in a + // larger octree cell because of its position (for example if it crosses the boundary of a cell it + // pops to the next higher cell. So we want to check to see that the entity is large enough to be seen + // before we consider including it. + float angularSize = frustum.getAngularSize(distance, radius); + + return angularSize > lodScaleFactor * MIN_ELEMENT_ANGULAR_DIAMETER && + frustum.intersects(position, distance, radius); + }); +} + DiffTraversal::DiffTraversal() { const int32_t MIN_PATH_DEPTH = 16; _path.reserve(MIN_PATH_DEPTH); @@ -262,7 +246,6 @@ DiffTraversal::Type DiffTraversal::prepareNewTraversal(const DiffTraversal::View void DiffTraversal::getNextVisibleElement(DiffTraversal::VisibleElement& next) { if (_path.empty()) { next.element.reset(); - next.intersection = ViewFrustum::OUTSIDE; return; } _getNextVisibleElementCallback(next); diff --git a/libraries/entities/src/DiffTraversal.h b/libraries/entities/src/DiffTraversal.h index 0fd014ac23..d62c7b8ee1 100644 --- a/libraries/entities/src/DiffTraversal.h +++ b/libraries/entities/src/DiffTraversal.h @@ -12,7 +12,7 @@ #ifndef hifi_DiffTraversal_h #define hifi_DiffTraversal_h -#include +#include #include "EntityTreeElement.h" @@ -24,19 +24,18 @@ public: class VisibleElement { public: EntityTreeElementPointer element; - ViewFrustum::intersection intersection { ViewFrustum::OUTSIDE }; }; // View is a struct with a ViewFrustum and LOD parameters class View { public: - bool isBigEnough(const AACube& cube, float minDiameter = MIN_ENTITY_ANGULAR_DIAMETER) const; - bool intersects(const AACube& cube) const; bool usesViewFrustums() const; bool isVerySimilar(const View& view) const; - ViewFrustum::intersection calculateIntersection(const AACube& cube) const; - ViewFrustums viewFrustums; + bool shouldTraverseElement(const EntityTreeElement& element) const; + float computePriority(const EntityItemPointer& entity) const; + + ConicalViewFrustums viewFrustums; uint64_t startTime { 0 }; float lodScaleFactor { 1.0f }; }; @@ -65,9 +64,6 @@ public: Type prepareNewTraversal(const DiffTraversal::View& view, EntityTreeElementPointer root); const View& getCurrentView() const { return _currentView; } - const View& getCompletedView() const { return _completedView; } - - bool doesCurrentUseViewFrustum() const { return _currentView.usesViewFrustums(); } uint64_t getStartOfCompletedTraversal() const { return _completedView.startTime; } bool finished() const { return _path.empty(); } diff --git a/assignment-client/src/entities/EntityPriorityQueue.h b/libraries/entities/src/EntityPriorityQueue.h similarity index 70% rename from assignment-client/src/entities/EntityPriorityQueue.h rename to libraries/entities/src/EntityPriorityQueue.h index 9210ac549f..354cd70af3 100644 --- a/assignment-client/src/entities/EntityPriorityQueue.h +++ b/libraries/entities/src/EntityPriorityQueue.h @@ -15,44 +15,14 @@ #include #include -#include -#include -#include - -const float SQRT_TWO_OVER_TWO = 0.7071067811865f; -const float DEFAULT_VIEW_RADIUS = 10.0f; - -// ConicalViewFrustum is an approximation of a ViewFrustum for fast calculation of sort priority. -class ConicalViewFrustum { -public: - ConicalViewFrustum() {} - ConicalViewFrustum(const ViewFrustum& viewFrustum) { set(viewFrustum); } - void set(const ViewFrustum& viewFrustum); - float computePriority(const AACube& cube) const; -private: - glm::vec3 _position { 0.0f, 0.0f, 0.0f }; - glm::vec3 _direction { 0.0f, 0.0f, 1.0f }; - float _sinAngle { SQRT_TWO_OVER_TWO }; - float _cosAngle { SQRT_TWO_OVER_TWO }; - float _radius { DEFAULT_VIEW_RADIUS }; -}; - -// Simple wrapper around a set of conical view frustums -class ConicalView { -public: - ConicalView() {} - void set(const DiffTraversal::View& view); - float computePriority(const AACube& cube) const; -private: - std::vector _conicalViewFrustums; -}; +#include "EntityItem.h" // PrioritizedEntity is a placeholder in a sorted queue. class PrioritizedEntity { public: - static const float DO_NOT_SEND; - static const float FORCE_REMOVE; - static const float WHEN_IN_DOUBT_PRIORITY; + static constexpr float DO_NOT_SEND { -1.0e-6f }; + static constexpr float FORCE_REMOVE { -1.0e-5f }; + static constexpr float WHEN_IN_DOUBT_PRIORITY { 1.0f }; PrioritizedEntity(EntityItemPointer entity, float priority, bool forceRemove = false) : _weakEntity(entity), _rawEntityPointer(entity.get()), _priority(priority), _forceRemove(forceRemove) {} EntityItemPointer getEntity() const { return _weakEntity.lock(); } diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 72710a6a7d..1776d63173 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -222,6 +222,12 @@ int unpackOrientationQuatFromSixBytes(const unsigned char* buffer, glm::quat& qu return 6; } +bool closeEnough(float a, float b, float relativeError) { + assert(relativeError >= 0.0f); + // NOTE: we add EPSILON to the denominator so we can avoid checking for division by zero. + // This method works fine when: fabsf(a + b) >> EPSILON + return fabsf(a - b) / (0.5f * fabsf(a + b) + EPSILON) < relativeError; +} // Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's // http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde, diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 5c9a8b5ca1..0e1af27cd2 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -137,6 +137,8 @@ int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, flo int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix); int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix); +bool closeEnough(float a, float b, float relativeError); + /// \return vec3 with euler angles in radians glm::vec3 safeEulerAngles(const glm::quat& q); diff --git a/libraries/shared/src/ViewFrustum.cpp b/libraries/shared/src/ViewFrustum.cpp index c2b92aac5f..c89a9fbd60 100644 --- a/libraries/shared/src/ViewFrustum.cpp +++ b/libraries/shared/src/ViewFrustum.cpp @@ -338,13 +338,6 @@ bool ViewFrustum::boxIntersectsKeyhole(const AABox& box) const { return true; } -bool closeEnough(float a, float b, float relativeError) { - assert(relativeError >= 0.0f); - // NOTE: we add EPSILON to the denominator so we can avoid checking for division by zero. - // This method works fine when: fabsf(a + b) >> EPSILON - return fabsf(a - b) / (0.5f * fabsf(a + b) + EPSILON) < relativeError; -} - // TODO: the slop and relative error should be passed in by argument rather than hard-coded. bool ViewFrustum::isVerySimilar(const ViewFrustum& other) const { const float MIN_POSITION_SLOP_SQUARED = 25.0f; // 5 meters squared diff --git a/libraries/shared/src/shared/ConicalViewFrustum.cpp b/libraries/shared/src/shared/ConicalViewFrustum.cpp new file mode 100644 index 0000000000..906bbc48a3 --- /dev/null +++ b/libraries/shared/src/shared/ConicalViewFrustum.cpp @@ -0,0 +1,125 @@ +// +// ConicalViewFrustum.cpp +// libraries/shared/src/shared +// +// Created by Clement Brisset 4/26/18 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ConicalViewFrustum.h" + +#include "../ViewFrustum.h" + +void ConicalViewFrustum::set(const ViewFrustum& viewFrustum) { + // The ConicalViewFrustum has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part. + // Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum. + _position = viewFrustum.getPosition(); + _direction = viewFrustum.getDirection(); + _radius = viewFrustum.getCenterRadius(); + _farClip = viewFrustum.getFarClip(); + + // Considering the rectangle intersection the frustum and the perpendicular plane 1 unit + // away from the frustum's origin + // We are looking for the angle between the ray that goes through the center of the rectangle + // and the ray that goes through one of the corners of the rectangle + // (Both rays coming from the frustum's origin) + // This angle will let us construct a cone in which the frustum is inscribed + // Let's define: + // A = aspect ratio = width / height + // fov = vertical field of view + // y = half height of the rectangle + // x = half width of the rectangle + // r = half diagonal of the rectangle + // then, we have: + // y / 1 = tan(fov / 2) + // x = A * y = A * tan(fov / 2) + // r^2 = x^2 + y^2 = (A^2 + 1) * tan^2(fov / 2) + // r / 1 = tan(angle) = sqrt((A^2 + 1) * tan^2(fov / 2)) + // angle = atan(sqrt((A^2 + 1) * tan^2(fov / 2))) + float A = viewFrustum.getAspectRatio(); + float t = tanf(0.5f * viewFrustum.getFieldOfView()); + + auto tan2Angle = (A * A + 1.0f) * (t * t); + _angle = atanf(sqrt(tan2Angle)); + + calculate(); +} + +void ConicalViewFrustum::calculate() { + _cosAngle = cosf(_angle); + _sinAngle = sqrtf(1.0f - _cosAngle * _cosAngle); +} + +bool ConicalViewFrustum::isVerySimilar(const ConicalViewFrustum& other) const { + const float MIN_POSITION_SLOP_SQUARED = 25.0f; // 5 meters squared + const float MIN_ANGLE_BETWEEN = 0.174533f; // radian angle between 2 vectors 10 degrees apart + const float MIN_RELATIVE_ERROR = 0.01f; // 1% + + return glm::distance2(_position, other._position) < MIN_POSITION_SLOP_SQUARED && + angleBetween(_direction, other._direction) > MIN_ANGLE_BETWEEN && + closeEnough(_angle, other._angle, MIN_RELATIVE_ERROR) && + closeEnough(_farClip, other._farClip, MIN_RELATIVE_ERROR) && + closeEnough(_radius, other._radius, MIN_RELATIVE_ERROR); +} + +bool ConicalViewFrustum::intersects(const glm::vec3& position, float distance, float radius) const { + if (distance < _radius + radius) { + // Inside keyhole radius + return true; + } + if (distance > _farClip + radius) { + // Past far clip + return false; + } + + // We check the angle between the center of the cube and the _direction of the view. + // If it is less than the sum of the half-angle from center of cone to outer edge plus + // the half apparent angle of the bounding sphere then it is in view. + // + // The math here is left as an exercise for the reader with the following hints: + // (1) We actually check the dot product of the cube's local position rather than the angle and + // (2) we take advantage of this trig identity: cos(A+B) = cos(A)*cos(B) - sin(A)*sin(B) + return glm::dot(position, _direction) > + sqrtf(distance * distance - radius * radius) * _cosAngle - radius * _sinAngle; +} + +bool ConicalViewFrustum::getAngularSize(float distance, float radius) const { + const float AVOID_DIVIDE_BY_ZERO = 0.001f; + float angularSize = radius / (distance + AVOID_DIVIDE_BY_ZERO); + return angularSize; +} + +int ConicalViewFrustum::serialize(unsigned char* destinationBuffer) const { + const unsigned char* startPosition = destinationBuffer; + + memcpy(destinationBuffer, &_position, sizeof(_position)); + destinationBuffer += sizeof(_position); + memcpy(destinationBuffer, &_direction, sizeof(_direction)); + destinationBuffer += sizeof(_direction); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _angle); + destinationBuffer += packClipValueToTwoByte(destinationBuffer, _farClip); + memcpy(destinationBuffer, &_radius, sizeof(_radius)); + destinationBuffer += sizeof(_radius); + + return destinationBuffer - startPosition; +} + +int ConicalViewFrustum::deserialize(const unsigned char* sourceBuffer) { + const unsigned char* startPosition = sourceBuffer; + + memcpy(&_position, sourceBuffer, sizeof(_position)); + sourceBuffer += sizeof(_position); + memcpy(&_direction, sourceBuffer, sizeof(_direction)); + sourceBuffer += sizeof(_direction); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*)sourceBuffer, &_angle); + sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer, _farClip); + memcpy(&_radius, sourceBuffer, sizeof(_radius)); + sourceBuffer += sizeof(_radius); + + calculate(); + + return sourceBuffer - startPosition; +} diff --git a/libraries/shared/src/shared/ConicalViewFrustum.h b/libraries/shared/src/shared/ConicalViewFrustum.h new file mode 100644 index 0000000000..3cadedda9d --- /dev/null +++ b/libraries/shared/src/shared/ConicalViewFrustum.h @@ -0,0 +1,64 @@ +// +// ConicalViewFrustum.h +// libraries/shared/src/shared +// +// Created by Clement Brisset 4/26/18 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ConicalViewFrustum_h +#define hifi_ConicalViewFrustum_h + +#include + +#include + +class AACube; +class ViewFrustum; +using ViewFrustums = std::vector; + +const float SQRT_TWO_OVER_TWO = 0.7071067811865f; +const float DEFAULT_VIEW_ANGLE = 1.0f; +const float DEFAULT_VIEW_RADIUS = 10.0f; +const float DEFAULT_VIEW_FAR_CLIP = 100.0f; + +// ConicalViewFrustum is an approximation of a ViewFrustum for fast calculation of sort priority. +class ConicalViewFrustum { +public: + ConicalViewFrustum() = default; + ConicalViewFrustum(const ViewFrustum& viewFrustum) { set(viewFrustum); } + + void set(const ViewFrustum& viewFrustum); + void calculate(); + + const glm::vec3& getPosition() const { return _position; } + const glm::vec3& getDirection() const { return _direction; } + float getAngle() const { return _angle; } + float getRadius() const { return _radius; } + float getFarClip() const { return _farClip; } + + bool isVerySimilar(const ConicalViewFrustum& other) const; + + bool intersects(const glm::vec3& position, float distance, float radius) const; + bool getAngularSize(float distance, float radius) const; + + int serialize(unsigned char* destinationBuffer) const; + int deserialize(const unsigned char* sourceBuffer); + +private: + glm::vec3 _position { 0.0f, 0.0f, 0.0f }; + glm::vec3 _direction { 0.0f, 0.0f, 1.0f }; + float _angle { DEFAULT_VIEW_ANGLE }; + float _radius { DEFAULT_VIEW_RADIUS }; + float _farClip { DEFAULT_VIEW_FAR_CLIP }; + + float _sinAngle { SQRT_TWO_OVER_TWO }; + float _cosAngle { SQRT_TWO_OVER_TWO }; +}; +using ConicalViewFrustums = std::vector; + + +#endif /* hifi_ConicalViewFrustum_h */ From e400eb4ed2c86f6132896404849b70193c63c4ae Mon Sep 17 00:00:00 2001 From: Clement Date: Mon, 30 Apr 2018 19:50:00 -0700 Subject: [PATCH 22/36] Rename ViewFrustum packets to AvatarQuery --- assignment-client/src/Agent.cpp | 2 +- assignment-client/src/avatars/AvatarMixer.cpp | 6 +++--- assignment-client/src/avatars/AvatarMixer.h | 2 +- interface/src/Application.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.cpp | 6 +++--- libraries/networking/src/udt/PacketHeaders.h | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0b373e511b..0183248648 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -618,7 +618,7 @@ void Agent::sendAvatarViewFrustum() { uint8_t numFrustums = 1; auto viewFrustumByteArray = view.toByteArray(); - auto avatarPacket = NLPacket::create(PacketType::ViewFrustum, viewFrustumByteArray.size() + sizeof(numFrustums)); + auto avatarPacket = NLPacket::create(PacketType::AvatarQuery, viewFrustumByteArray.size() + sizeof(numFrustums)); avatarPacket->writePrimitive(numFrustums); avatarPacket->write(viewFrustumByteArray); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 6353a1664f..d74c76032d 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -47,7 +47,7 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) : auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket"); packetReceiver.registerListener(PacketType::AdjustAvatarSorting, this, "handleAdjustAvatarSorting"); - packetReceiver.registerListener(PacketType::ViewFrustum, this, "handleViewFrustumPacket"); + packetReceiver.registerListener(PacketType::AvatarQuery, this, "handleAvatarQueryPacket"); packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); @@ -517,7 +517,7 @@ void AvatarMixer::handleAdjustAvatarSorting(QSharedPointer mess } -void AvatarMixer::handleViewFrustumPacket(QSharedPointer message, SharedNodePointer senderNode) { +void AvatarMixer::handleAvatarQueryPacket(QSharedPointer message, SharedNodePointer senderNode) { auto start = usecTimestampNow(); getOrCreateClientData(senderNode); @@ -683,7 +683,7 @@ void AvatarMixer::sendStatsPacket() { incomingPacketStats["handleNodeIgnoreRequestPacket"] = TIGHT_LOOP_STAT_UINT64(_handleNodeIgnoreRequestPacketElapsedTime); incomingPacketStats["handleRadiusIgnoreRequestPacket"] = TIGHT_LOOP_STAT_UINT64(_handleRadiusIgnoreRequestPacketElapsedTime); incomingPacketStats["handleRequestsDomainListDataPacket"] = TIGHT_LOOP_STAT_UINT64(_handleRequestsDomainListDataPacketElapsedTime); - incomingPacketStats["handleViewFrustumPacket"] = TIGHT_LOOP_STAT_UINT64(_handleViewFrustumPacketElapsedTime); + incomingPacketStats["handleAvatarQueryPacket"] = TIGHT_LOOP_STAT_UINT64(_handleViewFrustumPacketElapsedTime); singleCoreTasks["incoming_packets"] = incomingPacketStats; singleCoreTasks["sendStats"] = (float)_sendStatsElapsedTime; diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 1fbfd7338b..9ef5903eec 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -46,7 +46,7 @@ public slots: private slots: void queueIncomingPacket(QSharedPointer message, SharedNodePointer node); void handleAdjustAvatarSorting(QSharedPointer message, SharedNodePointer senderNode); - void handleViewFrustumPacket(QSharedPointer message, SharedNodePointer senderNode); + void handleAvatarQueryPacket(QSharedPointer message, SharedNodePointer senderNode); void handleAvatarIdentityPacket(QSharedPointer message, SharedNodePointer senderNode); void handleKillAvatarPacket(QSharedPointer message, SharedNodePointer senderNode); void handleNodeIgnoreRequestPacket(QSharedPointer message, SharedNodePointer senderNode); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5e10d29505..a1301ff43e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5852,7 +5852,7 @@ void Application::sendAvatarViewFrustum() { viewFrustumByteArray += _secondaryViewFrustum.toByteArray(); } - auto avatarPacket = NLPacket::create(PacketType::ViewFrustum, viewFrustumByteArray.size() + sizeof(numFrustums)); + auto avatarPacket = NLPacket::create(PacketType::AvatarQuery, viewFrustumByteArray.size() + sizeof(numFrustums)); avatarPacket->writePrimitive(numFrustums); avatarPacket->write(viewFrustumByteArray); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 17b0d90cfe..123e11b7c5 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -34,7 +34,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityPhysics: return static_cast(EntityVersion::MaterialData); case PacketType::EntityQuery: - return static_cast(EntityQueryPacketVersion::MultiFrustumQuery); + return static_cast(EntityQueryPacketVersion::ConicalFrustums); case PacketType::AvatarIdentity: case PacketType::AvatarData: case PacketType::BulkAvatarData: @@ -90,8 +90,8 @@ PacketVersion versionForPacketType(PacketType packetType) { return 18; // replace min_avatar_scale and max_avatar_scale with min_avatar_height and max_avatar_height case PacketType::Ping: return static_cast(PingVersion::IncludeConnectionID); - case PacketType::ViewFrustum: - return static_cast(ViewFrustumVersion::SendMultipleFrustums); + case PacketType::AvatarQuery: + return static_cast(AvatarQueryVersion::SendMultipleFrustums); default: return 20; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index c72bbb0129..20fe23a19a 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -103,7 +103,7 @@ public: RadiusIgnoreRequest, UsernameFromIDRequest, UsernameFromIDReply, - ViewFrustum, + AvatarQuery, RequestsDomainListData, PerAvatarGainSet, EntityScriptGetStatus, @@ -328,7 +328,7 @@ enum class PingVersion : PacketVersion { IncludeConnectionID = 18 }; -enum class ViewFrustumVersion : PacketVersion { +enum class AvatarQueryVersion : PacketVersion { SendMultipleFrustums = 21 }; From 67c119cd2ef39c44e970bb9cedbb2e76a41bdfc5 Mon Sep 17 00:00:00 2001 From: Clement Date: Mon, 30 Apr 2018 19:50:51 -0700 Subject: [PATCH 23/36] Send Entity Query via conical frustums --- .../src/entities/EntityTreeSendThread.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 ++- libraries/octree/src/OctreeQuery.cpp | 16 ++++------------ libraries/octree/src/OctreeQuery.h | 9 +++------ libraries/octree/src/OctreeQueryNode.cpp | 4 ++-- libraries/octree/src/OctreeQueryNode.h | 12 ++++++------ 6 files changed, 18 insertions(+), 28 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 0d943055f4..1851714f0d 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -108,7 +108,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O DiffTraversal::View newView; - ViewFrustum viewFrustum; + ConicalViewFrustum viewFrustum; if (nodeData->hasMainViewFrustum()) { nodeData->copyCurrentMainViewFrustum(viewFrustum); newView.viewFrustums.push_back(viewFrustum); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 20fe23a19a..1bedfdf3e6 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -245,7 +245,8 @@ enum class EntityQueryPacketVersion: PacketVersion { JSONFilterWithFamilyTree = 19, ConnectionIdentifier = 20, RemovedJurisdictions = 21, - MultiFrustumQuery = 22 + MultiFrustumQuery = 22, + ConicalFrustums = 23 }; enum class AssetServerPacketVersion: PacketVersion { diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 18e907cb8c..6b3f7b8e05 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -50,15 +50,11 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(frustumFlags); if (_hasMainFrustum) { - auto byteArray = _mainViewFrustum.toByteArray(); - memcpy(destinationBuffer, byteArray.constData(), byteArray.size()); - destinationBuffer += byteArray.size(); + destinationBuffer += _mainViewFrustum.serialize(destinationBuffer); } if (_hasSecondaryFrustum) { - auto byteArray = _secondaryViewFrustum.toByteArray(); - memcpy(destinationBuffer, byteArray.constData(), byteArray.size()); - destinationBuffer += byteArray.size(); + destinationBuffer += _secondaryViewFrustum.serialize(destinationBuffer); } // desired Max Octree PPS @@ -131,15 +127,11 @@ int OctreeQuery::parseData(ReceivedMessage& message) { _hasSecondaryFrustum = frustumFlags & QUERY_HAS_SECONDARY_FRUSTUM; if (_hasMainFrustum) { - auto bytesLeft = endPosition - sourceBuffer; - auto byteArray = QByteArray::fromRawData(reinterpret_cast(sourceBuffer), bytesLeft); - sourceBuffer += _mainViewFrustum.fromByteArray(byteArray); + sourceBuffer += _mainViewFrustum.deserialize(sourceBuffer); } if (_hasSecondaryFrustum) { - auto bytesLeft = endPosition - sourceBuffer; - auto byteArray = QByteArray::fromRawData(reinterpret_cast(sourceBuffer), bytesLeft); - sourceBuffer += _secondaryViewFrustum.fromByteArray(byteArray); + sourceBuffer += _secondaryViewFrustum.deserialize(sourceBuffer); } // desired Max Octree PPS diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index ef52e29f51..f28d4c317e 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -16,8 +16,7 @@ #include #include - -#include +#include #include "OctreeConstants.h" @@ -37,12 +36,10 @@ public: bool hasMainViewFrustum() const { return _hasMainFrustum; } void setMainViewFrustum(const ViewFrustum& viewFrustum) { _hasMainFrustum = true; _mainViewFrustum = viewFrustum; } void clearMainViewFrustum() { _hasMainFrustum = false; } - const ViewFrustum& getMainViewFrustum() const { return _mainViewFrustum; } bool hasSecondaryViewFrustum() const { return _hasSecondaryFrustum; } void setSecondaryViewFrustum(const ViewFrustum& viewFrustum) { _hasSecondaryFrustum = true; _secondaryViewFrustum = viewFrustum; } void clearSecondaryViewFrustum() { _hasSecondaryFrustum = false; } - const ViewFrustum& getSecondaryViewFrustum() const { return _secondaryViewFrustum; } // getters/setters for JSON filter QJsonObject getJSONParameters() { QReadLocker locker { &_jsonParametersLock }; return _jsonParameters; } @@ -68,9 +65,9 @@ public slots: protected: bool _hasMainFrustum { false }; - ViewFrustum _mainViewFrustum; + ConicalViewFrustum _mainViewFrustum; bool _hasSecondaryFrustum { false }; - ViewFrustum _secondaryViewFrustum; + ConicalViewFrustum _secondaryViewFrustum; // octree server sending items int _maxQueryPPS = DEFAULT_MAX_OCTREE_PPS; diff --git a/libraries/octree/src/OctreeQueryNode.cpp b/libraries/octree/src/OctreeQueryNode.cpp index d6e9343896..568504a344 100644 --- a/libraries/octree/src/OctreeQueryNode.cpp +++ b/libraries/octree/src/OctreeQueryNode.cpp @@ -139,12 +139,12 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by } } -void OctreeQueryNode::copyCurrentMainViewFrustum(ViewFrustum& viewOut) const { +void OctreeQueryNode::copyCurrentMainViewFrustum(ConicalViewFrustum& viewOut) const { QMutexLocker viewLocker(&_viewMutex); viewOut = _currentMainViewFrustum; } -void OctreeQueryNode::copyCurrentSecondaryViewFrustum(ViewFrustum& viewOut) const { +void OctreeQueryNode::copyCurrentSecondaryViewFrustum(ConicalViewFrustum& viewOut) const { QMutexLocker viewLocker(&_viewMutex); viewOut = _currentSecondaryViewFrustum; } diff --git a/libraries/octree/src/OctreeQueryNode.h b/libraries/octree/src/OctreeQueryNode.h index d8f05c4043..13337c2c69 100644 --- a/libraries/octree/src/OctreeQueryNode.h +++ b/libraries/octree/src/OctreeQueryNode.h @@ -14,14 +14,14 @@ #include -#include +#include + #include "OctreeConstants.h" #include "OctreeElementBag.h" #include "OctreePacketData.h" #include "OctreeQuery.h" #include "OctreeSceneStats.h" #include "SentPacketHistory.h" -#include class OctreeSendThread; class OctreeServer; @@ -49,8 +49,8 @@ public: OctreeElementExtraEncodeData extraEncodeData; - void copyCurrentMainViewFrustum(ViewFrustum& viewOut) const; - void copyCurrentSecondaryViewFrustum(ViewFrustum& viewOut) const; + void copyCurrentMainViewFrustum(ConicalViewFrustum& viewOut) const; + void copyCurrentSecondaryViewFrustum(ConicalViewFrustum& viewOut) const; // These are not classic setters because they are calculating and maintaining state // which is set asynchronously through the network receive @@ -97,8 +97,8 @@ private: quint64 _firstSuppressedPacket { usecTimestampNow() }; mutable QMutex _viewMutex { QMutex::Recursive }; - ViewFrustum _currentMainViewFrustum; - ViewFrustum _currentSecondaryViewFrustum; + ConicalViewFrustum _currentMainViewFrustum; + ConicalViewFrustum _currentSecondaryViewFrustum; bool _viewFrustumChanging { false }; bool _viewFrustumJustStoppedChanging { true }; From b4ea32bbb6fb7884dbbe8dd0450ae98ac0b0cdfa Mon Sep 17 00:00:00 2001 From: Clement Date: Mon, 30 Apr 2018 19:51:18 -0700 Subject: [PATCH 24/36] Correctly compute conical frustum for irregular ones --- .../shared/src/shared/ConicalViewFrustum.cpp | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/libraries/shared/src/shared/ConicalViewFrustum.cpp b/libraries/shared/src/shared/ConicalViewFrustum.cpp index 906bbc48a3..c73a722f0e 100644 --- a/libraries/shared/src/shared/ConicalViewFrustum.cpp +++ b/libraries/shared/src/shared/ConicalViewFrustum.cpp @@ -17,38 +17,24 @@ void ConicalViewFrustum::set(const ViewFrustum& viewFrustum) { // The ConicalViewFrustum has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part. // Why? Because approximate intersection tests are much faster to compute for a cone than for a frustum. _position = viewFrustum.getPosition(); - _direction = viewFrustum.getDirection(); _radius = viewFrustum.getCenterRadius(); _farClip = viewFrustum.getFarClip(); - // Considering the rectangle intersection the frustum and the perpendicular plane 1 unit - // away from the frustum's origin - // We are looking for the angle between the ray that goes through the center of the rectangle - // and the ray that goes through one of the corners of the rectangle - // (Both rays coming from the frustum's origin) - // This angle will let us construct a cone in which the frustum is inscribed - // Let's define: - // A = aspect ratio = width / height - // fov = vertical field of view - // y = half height of the rectangle - // x = half width of the rectangle - // r = half diagonal of the rectangle - // then, we have: - // y / 1 = tan(fov / 2) - // x = A * y = A * tan(fov / 2) - // r^2 = x^2 + y^2 = (A^2 + 1) * tan^2(fov / 2) - // r / 1 = tan(angle) = sqrt((A^2 + 1) * tan^2(fov / 2)) - // angle = atan(sqrt((A^2 + 1) * tan^2(fov / 2))) - float A = viewFrustum.getAspectRatio(); - float t = tanf(0.5f * viewFrustum.getFieldOfView()); + auto topLeft = viewFrustum.getNearTopLeft() - _position; + auto topRight = viewFrustum.getNearTopRight() - _position; + auto bottomLeft = viewFrustum.getNearBottomLeft() - _position; + auto bottomRight = viewFrustum.getNearBottomRight() - _position; + auto centerAxis = 0.25f * (topLeft + topRight + bottomLeft + bottomRight); // Take the average - auto tan2Angle = (A * A + 1.0f) * (t * t); - _angle = atanf(sqrt(tan2Angle)); - - calculate(); + _direction = glm::normalize(centerAxis); + _angle = std::max(std::max(angleBetween(_direction, topLeft), + angleBetween(_direction, topRight)), + std::max(angleBetween(_direction, bottomLeft), + angleBetween(_direction, bottomRight))); } void ConicalViewFrustum::calculate() { + // Pre-compute cos and sin for faster checks _cosAngle = cosf(_angle); _sinAngle = sqrtf(1.0f - _cosAngle * _cosAngle); } From 3283c5eaeca6bb13ddd70add0f93e88b91804916 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 1 May 2018 12:37:51 -0700 Subject: [PATCH 25/36] Fix inverted comparaison --- libraries/octree/src/OctreeQuery.cpp | 1 - libraries/shared/src/shared/ConicalViewFrustum.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 6b3f7b8e05..7aa702138f 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -95,7 +95,6 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { int OctreeQuery::parseData(ReceivedMessage& message) { const unsigned char* startPosition = reinterpret_cast(message.getRawMessage()); - const unsigned char* endPosition = startPosition + message.getSize(); const unsigned char* sourceBuffer = startPosition; // unpack the connection ID diff --git a/libraries/shared/src/shared/ConicalViewFrustum.cpp b/libraries/shared/src/shared/ConicalViewFrustum.cpp index c73a722f0e..8538543da6 100644 --- a/libraries/shared/src/shared/ConicalViewFrustum.cpp +++ b/libraries/shared/src/shared/ConicalViewFrustum.cpp @@ -45,7 +45,7 @@ bool ConicalViewFrustum::isVerySimilar(const ConicalViewFrustum& other) const { const float MIN_RELATIVE_ERROR = 0.01f; // 1% return glm::distance2(_position, other._position) < MIN_POSITION_SLOP_SQUARED && - angleBetween(_direction, other._direction) > MIN_ANGLE_BETWEEN && + angleBetween(_direction, other._direction) < MIN_ANGLE_BETWEEN && closeEnough(_angle, other._angle, MIN_RELATIVE_ERROR) && closeEnough(_farClip, other._farClip, MIN_RELATIVE_ERROR) && closeEnough(_radius, other._radius, MIN_RELATIVE_ERROR); From 27c471ee9774f2fd98c0584402ad7a7242c5ad18 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 1 May 2018 15:57:26 -0700 Subject: [PATCH 26/36] Move all wire frustums to conical frustums --- assignment-client/src/Agent.cpp | 14 +++- .../src/avatars/AvatarMixerClientData.cpp | 15 ++-- .../src/avatars/AvatarMixerClientData.h | 6 +- .../src/entities/EntityTreeSendThread.cpp | 11 +-- .../src/octree/OctreeHeadlessViewer.cpp | 5 +- .../src/octree/OctreeSendThread.cpp | 2 +- interface/src/Application.cpp | 80 ++++++++++--------- interface/src/Application.h | 14 ++-- interface/src/avatar/AvatarManager.cpp | 13 +-- .../src/EntityTreeRenderer.cpp | 19 +---- .../src/EntityTreeRenderer.h | 3 +- libraries/octree/src/OctreeQuery.cpp | 46 ++++------- libraries/octree/src/OctreeQuery.h | 15 +--- libraries/octree/src/OctreeQueryNode.cpp | 29 +++---- libraries/octree/src/OctreeQueryNode.h | 6 +- libraries/octree/src/OctreeUtils.h | 3 +- .../src/AbstractViewStateInterface.h | 6 +- libraries/shared/src/NumericalConstants.h | 2 + libraries/shared/src/PrioritySortUtil.h | 16 ++-- libraries/shared/src/ViewFrustum.cpp | 63 --------------- libraries/shared/src/ViewFrustum.h | 3 - .../shared/src/shared/ConicalViewFrustum.cpp | 47 +++++++++-- .../shared/src/shared/ConicalViewFrustum.h | 8 +- tests/render-perf/src/main.cpp | 12 +-- 24 files changed, 181 insertions(+), 257 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0183248648..da811b8af5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -614,13 +614,19 @@ void Agent::sendAvatarViewFrustum() { view.setPosition(scriptedAvatar->getWorldPosition()); view.setOrientation(scriptedAvatar->getHeadOrientation()); view.calculate(); + ConicalViewFrustum conicalView { view }; + + auto avatarPacket = NLPacket::create(PacketType::AvatarQuery); + auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); + auto bufferStart = destinationBuffer; uint8_t numFrustums = 1; - auto viewFrustumByteArray = view.toByteArray(); + memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); + destinationBuffer += sizeof(numFrustums); - auto avatarPacket = NLPacket::create(PacketType::AvatarQuery, viewFrustumByteArray.size() + sizeof(numFrustums)); - avatarPacket->writePrimitive(numFrustums); - avatarPacket->write(viewFrustumByteArray); + destinationBuffer += conicalView.serialize(destinationBuffer); + + avatarPacket->setPayloadSize(destinationBuffer - bufferStart); DependencyManager::get()->broadcastToNodes(std::move(avatarPacket), { NodeType::AvatarMixer }); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index a8e5a7c541..aa93fc9e08 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -128,15 +128,16 @@ void AvatarMixerClientData::removeFromRadiusIgnoringSet(SharedNodePointer self, void AvatarMixerClientData::readViewFrustumPacket(QByteArray message) { _currentViewFrustums.clear(); + + auto sourceBuffer = reinterpret_cast(message.constData()); uint8_t numFrustums = 0; - memcpy(&numFrustums, message.constData(), sizeof(numFrustums)); - message.remove(0, sizeof(numFrustums)); + memcpy(&numFrustums, sourceBuffer, sizeof(numFrustums)); + sourceBuffer += sizeof(numFrustums); for (uint8_t i = 0; i < numFrustums; ++i) { - ViewFrustum frustum; - auto bytesRead = frustum.fromByteArray(message); - message.remove(0, bytesRead); + ConicalViewFrustum frustum; + sourceBuffer += frustum.deserialize(sourceBuffer); _currentViewFrustums.push_back(frustum); } @@ -144,8 +145,8 @@ void AvatarMixerClientData::readViewFrustumPacket(QByteArray message) { bool AvatarMixerClientData::otherAvatarInView(const AABox& otherAvatarBox) { return std::any_of(std::begin(_currentViewFrustums), std::end(_currentViewFrustums), - [&](const ViewFrustum& viewFrustum) { - return viewFrustum.boxIntersectsKeyhole(otherAvatarBox); + [&](const ConicalViewFrustum& viewFrustum) { + return viewFrustum.intersects(otherAvatarBox); }); } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index f17404b79f..f3b2b587ee 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps"; const QString INBOUND_AVATAR_DATA_STATS_KEY = "inbound_av_data_kbps"; @@ -110,7 +110,7 @@ public: bool getRequestsDomainListData() { return _requestsDomainListData; } void setRequestsDomainListData(bool requesting) { _requestsDomainListData = requesting; } - const ViewFrustums& getViewFrustums() const { return _currentViewFrustums; } + const ConicalViewFrustums& getViewFrustums() const { return _currentViewFrustums; } uint64_t getLastOtherAvatarEncodeTime(QUuid otherAvatar) const; void setLastOtherAvatarEncodeTime(const QUuid& otherAvatar, uint64_t time); @@ -150,7 +150,7 @@ private: SimpleMovingAverage _avgOtherAvatarDataRate; std::unordered_set _radiusIgnoredOthers; - ViewFrustums _currentViewFrustums; + ConicalViewFrustums _currentViewFrustums; int _recentOtherAvatarsInView { 0 }; int _recentOtherAvatarsOutOfView { 0 }; diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 1851714f0d..f008ef9925 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -107,16 +107,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O DiffTraversal::View newView; - - ConicalViewFrustum viewFrustum; - if (nodeData->hasMainViewFrustum()) { - nodeData->copyCurrentMainViewFrustum(viewFrustum); - newView.viewFrustums.push_back(viewFrustum); - } - if (nodeData->hasSecondaryViewFrustum()) { - nodeData->copyCurrentSecondaryViewFrustum(viewFrustum); - newView.viewFrustums.push_back(viewFrustum); - } + newView.viewFrustums = nodeData->getCurrentViews(); int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); newView.lodScaleFactor = powf(2.0f, lodLevelOffset); diff --git a/assignment-client/src/octree/OctreeHeadlessViewer.cpp b/assignment-client/src/octree/OctreeHeadlessViewer.cpp index 6d91a134c2..039dbdab78 100644 --- a/assignment-client/src/octree/OctreeHeadlessViewer.cpp +++ b/assignment-client/src/octree/OctreeHeadlessViewer.cpp @@ -19,7 +19,10 @@ void OctreeHeadlessViewer::queryOctree() { PacketType packetType = getMyQueryMessageType(); if (_hasViewFrustum) { - _octreeQuery.setMainViewFrustum(_viewFrustum); + ConicalViewFrustums views { _viewFrustum }; + _octreeQuery.setConicalViews(views); + } else { + _octreeQuery.clearConicalViews(); } auto nodeList = DependencyManager::get(); diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 40c052659d..482b20272a 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -330,7 +330,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* } else { // we aren't forcing a full scene, check if something else suggests we should isFullScene = nodeData->haveJSONParametersChanged() || - (nodeData->hasMainViewFrustum() && + (nodeData->hasConicalViews() && (nodeData->getViewFrustumJustStoppedChanging() || nodeData->hasLodChanged())); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a1301ff43e..d14af685f0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5230,10 +5230,10 @@ void Application::updateSecondaryCameraViewFrustum() { assert(camera); if (!camera->isEnabled()) { - _hasSecondaryViewFrustum = false; return; } + ViewFrustum secondaryViewFrustum; if (camera->mirrorProjection && !camera->attachedEntityId.isNull()) { auto entityScriptingInterface = DependencyManager::get(); auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId); @@ -5258,36 +5258,37 @@ void Application::updateSecondaryCameraViewFrustum() { // set frustum position to be mirrored camera and set orientation to mirror's adjusted rotation glm::quat mirrorCameraOrientation = glm::quat_cast(worldFromMirrorRotation); - _secondaryViewFrustum.setPosition(mirrorCameraPositionWorld); - _secondaryViewFrustum.setOrientation(mirrorCameraOrientation); + secondaryViewFrustum.setPosition(mirrorCameraPositionWorld); + secondaryViewFrustum.setOrientation(mirrorCameraOrientation); // build frustum using mirror space translation of mirrored camera float nearClip = mirrorCameraPositionMirror.z + mirrorPropertiesDimensions.z * 2.0f; glm::vec3 upperRight = halfMirrorPropertiesDimensions - mirrorCameraPositionMirror; glm::vec3 bottomLeft = -halfMirrorPropertiesDimensions - mirrorCameraPositionMirror; glm::mat4 frustum = glm::frustum(bottomLeft.x, upperRight.x, bottomLeft.y, upperRight.y, nearClip, camera->farClipPlaneDistance); - _secondaryViewFrustum.setProjection(frustum); + secondaryViewFrustum.setProjection(frustum); } else { if (!camera->attachedEntityId.isNull()) { auto entityScriptingInterface = DependencyManager::get(); auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId); - _secondaryViewFrustum.setPosition(entityProperties.getPosition()); - _secondaryViewFrustum.setOrientation(entityProperties.getRotation()); + secondaryViewFrustum.setPosition(entityProperties.getPosition()); + secondaryViewFrustum.setOrientation(entityProperties.getRotation()); } else { - _secondaryViewFrustum.setPosition(camera->position); - _secondaryViewFrustum.setOrientation(camera->orientation); + secondaryViewFrustum.setPosition(camera->position); + secondaryViewFrustum.setOrientation(camera->orientation); } float aspectRatio = (float)camera->textureWidth / (float)camera->textureHeight; - _secondaryViewFrustum.setProjection(camera->vFoV, + secondaryViewFrustum.setProjection(camera->vFoV, aspectRatio, camera->nearClipPlaneDistance, camera->farClipPlaneDistance); } // Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera, // which is not what we want here. - _secondaryViewFrustum.calculate(); - _hasSecondaryViewFrustum = true; + secondaryViewFrustum.calculate(); + + _conicalViews.push_back(secondaryViewFrustum); } static bool domainLoadingInProgress = false; @@ -5644,6 +5645,8 @@ void Application::update(float deltaTime) { QMutexLocker viewLocker(&_viewMutex); _myCamera.loadViewFrustum(_viewFrustum); + _conicalViews.clear(); + _conicalViews.push_back(_viewFrustum); // TODO: Fix this by modeling the way the secondary camera works on how the main camera works // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary // camera should be. @@ -5660,18 +5663,29 @@ void Application::update(float deltaTime) { quint64 sinceLastQuery = now - _lastQueriedTime; const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; bool queryIsDue = sinceLastQuery > TOO_LONG_SINCE_LAST_QUERY; - bool viewIsDifferentEnough = !_lastQueriedViewFrustum.isVerySimilar(_viewFrustum); - viewIsDifferentEnough |= _hasSecondaryViewFrustum && !_lastQueriedSecondaryViewFrustum.isVerySimilar(_secondaryViewFrustum); + + bool viewIsDifferentEnough = false; + if (_conicalViews.size() == _lastQueriedViews.size()) { + for (size_t i = 0; i < _conicalViews.size(); ++i) { + if (!_conicalViews[i].isVerySimilar(_lastQueriedViews[i])) { + viewIsDifferentEnough = true; + break; + } + } + } else { + viewIsDifferentEnough = true; + } + // if it's been a while since our last query or the view has significantly changed then send a query, otherwise suppress it if (queryIsDue || viewIsDifferentEnough) { - _lastQueriedTime = now; if (DependencyManager::get()->shouldRenderEntities()) { queryOctree(NodeType::EntityServer, PacketType::EntityQuery); } sendAvatarViewFrustum(); - _lastQueriedViewFrustum = _viewFrustum; - _lastQueriedSecondaryViewFrustum = _secondaryViewFrustum; + + _lastQueriedViews = _conicalViews; + _lastQueriedTime = now; } } @@ -5844,17 +5858,19 @@ void Application::update(float deltaTime) { } void Application::sendAvatarViewFrustum() { - uint8_t numFrustums = 1; - QByteArray viewFrustumByteArray = _viewFrustum.toByteArray(); + auto avatarPacket = NLPacket::create(PacketType::AvatarQuery); + auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); + unsigned char* bufferStart = destinationBuffer; - if (_hasSecondaryViewFrustum) { - ++numFrustums; - viewFrustumByteArray += _secondaryViewFrustum.toByteArray(); + uint8_t numFrustums = _conicalViews.size(); + memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); + destinationBuffer += sizeof(numFrustums); + + for (const auto& view : _conicalViews) { + destinationBuffer += view.serialize(destinationBuffer); } - auto avatarPacket = NLPacket::create(PacketType::AvatarQuery, viewFrustumByteArray.size() + sizeof(numFrustums)); - avatarPacket->writePrimitive(numFrustums); - avatarPacket->write(viewFrustumByteArray); + avatarPacket->setPayloadSize(destinationBuffer - bufferStart); DependencyManager::get()->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer); } @@ -5916,16 +5932,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) { return; // bail early if settings are not loaded } - ViewFrustum viewFrustum; - copyViewFrustum(viewFrustum); - _octreeQuery.setMainViewFrustum(viewFrustum); - - if (hasSecondaryViewFrustum()) { - copySecondaryViewFrustum(viewFrustum); - _octreeQuery.setSecondaryViewFrustum(viewFrustum); - } else { - _octreeQuery.clearSecondaryViewFrustum(); - } + _octreeQuery.setConicalViews(_conicalViews); auto lodManager = DependencyManager::get(); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); @@ -6010,11 +6017,6 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -void Application::copySecondaryViewFrustum(ViewFrustum& viewOut) const { - QMutexLocker viewLocker(&_viewMutex); - viewOut = _secondaryViewFrustum; -} - void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); DependencyManager::get()->reset(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 83e719333d..6d749f9458 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -175,14 +176,14 @@ public: Camera& getCamera() { return _myCamera; } const Camera& getCamera() const { return _myCamera; } // Represents the current view frustum of the avatar. - void copyViewFrustum(ViewFrustum& viewOut) const override; - void copySecondaryViewFrustum(ViewFrustum& viewOut) const override; - bool hasSecondaryViewFrustum() const override { return _hasSecondaryViewFrustum; } + void copyViewFrustum(ViewFrustum& viewOut) const; // Represents the view frustum of the current rendering pass, // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc void copyDisplayViewFrustum(ViewFrustum& viewOut) const; + const ConicalViewFrustums& getConicalViews() const override { return _conicalViews; } + const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } QSharedPointer getEntities() const { return DependencyManager::get(); } QUndoStack* getUndoStack() { return &_undoStack; } @@ -574,11 +575,10 @@ private: mutable QMutex _viewMutex { QMutex::Recursive }; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. - ViewFrustum _lastQueriedViewFrustum; // last view frustum used to query octree servers ViewFrustum _displayViewFrustum; - ViewFrustum _secondaryViewFrustum; - ViewFrustum _lastQueriedSecondaryViewFrustum; // last secondary view frustum used to query octree servers - bool _hasSecondaryViewFrustum; + + ConicalViewFrustums _conicalViews; + ConicalViewFrustums _lastQueriedViews; // last views used to query servers quint64 _lastQueriedTime; OctreeQuery _octreeQuery { true }; // NodeData derived class for querying octee cells from octree servers diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 087e23a933..d24618fada 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "Application.h" #include "AvatarManager.h" @@ -156,17 +157,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { }; - ViewFrustums views; - - ViewFrustum view; - qApp->copyCurrentViewFrustum(view); - views.push_back(view); - - if (qApp->hasSecondaryViewFrustum()) { - qApp->copySecondaryViewFrustum(view); - views.push_back(view); - } - + const auto& views = qApp->getConicalViews(); PrioritySortUtil::PriorityQueue sortedAvatars(views, AvatarData::_avatarSortCoefficientSize, AvatarData::_avatarSortCoefficientCenter, diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 6dd13c7332..600d1c32a8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -296,8 +296,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r } } -void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene, const ViewFrustums& views, - render::Transaction& transaction) { +void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene, render::Transaction& transaction) { PROFILE_RANGE_EX(simulation_physics, "ChangeInScene", 0xffff00ff, (uint64_t)_changedEntities.size()); PerformanceTimer pt("change"); std::unordered_set changedEntities; @@ -358,6 +357,8 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene // prioritize and sort the renderables uint64_t sortStart = usecTimestampNow(); + + const auto& views = _viewState->getConicalViews(); PrioritySortUtil::PriorityQueue sortedRenderables(views); { PROFILE_RANGE_EX(simulation_physics, "SortRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size()); @@ -417,19 +418,7 @@ void EntityTreeRenderer::update(bool simulate) { render::Transaction transaction; addPendingEntities(scene, transaction); - ViewFrustums views; - - ViewFrustum view; - _viewState->copyViewFrustum(view); - views.push_back(view); - - if (_viewState->hasSecondaryViewFrustum()) { - _viewState->copySecondaryViewFrustum(view); - views.push_back(view); - } - - - updateChangedEntities(scene, views, transaction); + updateChangedEntities(scene, transaction); scene->enqueueTransaction(transaction); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 9ed4f9d21d..882ec2fd5b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -148,8 +148,7 @@ protected: private: void addPendingEntities(const render::ScenePointer& scene, render::Transaction& transaction); - void updateChangedEntities(const render::ScenePointer& scene, const ViewFrustums& views, - render::Transaction& transaction); + void updateChangedEntities(const render::ScenePointer& scene, render::Transaction& transaction); EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 7aa702138f..072774f0f5 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -18,10 +18,6 @@ #include #include -using QueryFlags = uint8_t; -const QueryFlags QUERY_HAS_MAIN_FRUSTUM = 1U << 0; -const QueryFlags QUERY_HAS_SECONDARY_FRUSTUM = 1U << 1; - OctreeQuery::OctreeQuery(bool randomizeConnectionID) { if (randomizeConnectionID) { // randomize our initial octree query connection ID using random_device @@ -38,23 +34,13 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { memcpy(destinationBuffer, &_connectionID, sizeof(_connectionID)); destinationBuffer += sizeof(_connectionID); - // flags for wether the frustums are present - QueryFlags frustumFlags = 0; - if (_hasMainFrustum) { - frustumFlags |= QUERY_HAS_MAIN_FRUSTUM; - } - if (_hasSecondaryFrustum) { - frustumFlags |= QUERY_HAS_SECONDARY_FRUSTUM; - } - memcpy(destinationBuffer, &frustumFlags, sizeof(frustumFlags)); - destinationBuffer += sizeof(frustumFlags); + // Number of frustums + uint8_t numFrustums = _conicalViews.size(); + memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); + destinationBuffer += sizeof(numFrustums); - if (_hasMainFrustum) { - destinationBuffer += _mainViewFrustum.serialize(destinationBuffer); - } - - if (_hasSecondaryFrustum) { - destinationBuffer += _secondaryViewFrustum.serialize(destinationBuffer); + for (const auto& view : _conicalViews) { + destinationBuffer += view.serialize(destinationBuffer); } // desired Max Octree PPS @@ -118,19 +104,15 @@ int OctreeQuery::parseData(ReceivedMessage& message) { } // check if this query uses a view frustum - QueryFlags frustumFlags { 0 }; - memcpy(&frustumFlags, sourceBuffer, sizeof(frustumFlags)); - sourceBuffer += sizeof(frustumFlags); + uint8_t numFrustums = 0; + memcpy(&numFrustums, sourceBuffer, sizeof(numFrustums)); + sourceBuffer += sizeof(numFrustums); - _hasMainFrustum = frustumFlags & QUERY_HAS_MAIN_FRUSTUM; - _hasSecondaryFrustum = frustumFlags & QUERY_HAS_SECONDARY_FRUSTUM; - - if (_hasMainFrustum) { - sourceBuffer += _mainViewFrustum.deserialize(sourceBuffer); - } - - if (_hasSecondaryFrustum) { - sourceBuffer += _secondaryViewFrustum.deserialize(sourceBuffer); + _conicalViews.clear(); + for (int i = 0; i < numFrustums; ++i) { + ConicalViewFrustum view; + sourceBuffer += view.deserialize(sourceBuffer); + _conicalViews.push_back(view); } // desired Max Octree PPS diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index f28d4c317e..7dfc1cfaaf 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -33,13 +33,9 @@ public: int getBroadcastData(unsigned char* destinationBuffer); int parseData(ReceivedMessage& message) override; - bool hasMainViewFrustum() const { return _hasMainFrustum; } - void setMainViewFrustum(const ViewFrustum& viewFrustum) { _hasMainFrustum = true; _mainViewFrustum = viewFrustum; } - void clearMainViewFrustum() { _hasMainFrustum = false; } - - bool hasSecondaryViewFrustum() const { return _hasSecondaryFrustum; } - void setSecondaryViewFrustum(const ViewFrustum& viewFrustum) { _hasSecondaryFrustum = true; _secondaryViewFrustum = viewFrustum; } - void clearSecondaryViewFrustum() { _hasSecondaryFrustum = false; } + bool hasConicalViews() const { return !_conicalViews.empty(); } + void setConicalViews(ConicalViewFrustums views) { _conicalViews = views; } + void clearConicalViews() { _conicalViews.clear(); } // getters/setters for JSON filter QJsonObject getJSONParameters() { QReadLocker locker { &_jsonParametersLock }; return _jsonParameters; } @@ -64,10 +60,7 @@ public slots: void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; } protected: - bool _hasMainFrustum { false }; - ConicalViewFrustum _mainViewFrustum; - bool _hasSecondaryFrustum { false }; - ConicalViewFrustum _secondaryViewFrustum; + ConicalViewFrustums _conicalViews; // octree server sending items int _maxQueryPPS = DEFAULT_MAX_OCTREE_PPS; diff --git a/libraries/octree/src/OctreeQueryNode.cpp b/libraries/octree/src/OctreeQueryNode.cpp index 568504a344..2d1d89a11c 100644 --- a/libraries/octree/src/OctreeQueryNode.cpp +++ b/libraries/octree/src/OctreeQueryNode.cpp @@ -139,23 +139,13 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by } } -void OctreeQueryNode::copyCurrentMainViewFrustum(ConicalViewFrustum& viewOut) const { - QMutexLocker viewLocker(&_viewMutex); - viewOut = _currentMainViewFrustum; -} - -void OctreeQueryNode::copyCurrentSecondaryViewFrustum(ConicalViewFrustum& viewOut) const { - QMutexLocker viewLocker(&_viewMutex); - viewOut = _currentSecondaryViewFrustum; -} - bool OctreeQueryNode::updateCurrentViewFrustum() { // if shutting down, return immediately if (_isShuttingDown) { return false; } - if (!_hasMainFrustum && !_hasSecondaryFrustum) { + if (!hasConicalViews()) { // this client does not use a view frustum so the view frustum for this query has not changed return false; } @@ -164,12 +154,17 @@ bool OctreeQueryNode::updateCurrentViewFrustum() { { // if there has been a change, then recalculate QMutexLocker viewLocker(&_viewMutex); - if (_hasMainFrustum && !_mainViewFrustum.isVerySimilar(_currentMainViewFrustum)) { - _currentMainViewFrustum = _mainViewFrustum; - currentViewFrustumChanged = true; - } - if (_hasSecondaryFrustum && !_secondaryViewFrustum.isVerySimilar(_currentSecondaryViewFrustum)) { - _currentSecondaryViewFrustum = _secondaryViewFrustum; + + if (_conicalViews.size() == _currentConicalViews.size()) { + for (size_t i = 0; i < _conicalViews.size(); ++i) { + if (!_conicalViews[i].isVerySimilar(_currentConicalViews[i])) { + _currentConicalViews = _conicalViews; + currentViewFrustumChanged = true; + break; + } + } + } else { + _currentConicalViews = _conicalViews; currentViewFrustumChanged = true; } } diff --git a/libraries/octree/src/OctreeQueryNode.h b/libraries/octree/src/OctreeQueryNode.h index 13337c2c69..d984e048c1 100644 --- a/libraries/octree/src/OctreeQueryNode.h +++ b/libraries/octree/src/OctreeQueryNode.h @@ -49,8 +49,7 @@ public: OctreeElementExtraEncodeData extraEncodeData; - void copyCurrentMainViewFrustum(ConicalViewFrustum& viewOut) const; - void copyCurrentSecondaryViewFrustum(ConicalViewFrustum& viewOut) const; + const ConicalViewFrustums& getCurrentViews() const { return _currentConicalViews; } // These are not classic setters because they are calculating and maintaining state // which is set asynchronously through the network receive @@ -97,8 +96,7 @@ private: quint64 _firstSuppressedPacket { usecTimestampNow() }; mutable QMutex _viewMutex { QMutex::Recursive }; - ConicalViewFrustum _currentMainViewFrustum; - ConicalViewFrustum _currentSecondaryViewFrustum; + ConicalViewFrustums _currentConicalViews; bool _viewFrustumChanging { false }; bool _viewFrustumJustStoppedChanging { true }; diff --git a/libraries/octree/src/OctreeUtils.h b/libraries/octree/src/OctreeUtils.h index 58ab366d8d..dff56cad64 100644 --- a/libraries/octree/src/OctreeUtils.h +++ b/libraries/octree/src/OctreeUtils.h @@ -12,6 +12,8 @@ #ifndef hifi_OctreeUtils_h #define hifi_OctreeUtils_h +#include + #include "OctreeConstants.h" class AABox; @@ -33,7 +35,6 @@ float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust // MIN_ELEMENT_ANGULAR_DIAMETER = angular diameter of 1x1x1m cube at 400m = sqrt(3) / 400 = 0.0043301 radians ~= 0.25 degrees const float MIN_ELEMENT_ANGULAR_DIAMETER = 0.0043301f; // radians // NOTE: the entity bounding cube is larger than the smallest possible containing octree element by sqrt(3) -const float SQRT_THREE = 1.73205080f; const float MIN_ENTITY_ANGULAR_DIAMETER = MIN_ELEMENT_ANGULAR_DIAMETER * SQRT_THREE; const float MIN_VISIBLE_DISTANCE = 0.0001f; // helps avoid divide-by-zero check diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 9d781b7d18..b90e291da5 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -24,6 +24,8 @@ class Transform; class QThread; class ViewFrustum; class PickRay; +class ConicalViewFrustum; +using ConicalViewFrustums = std::vector; /// Interface provided by Application to other objects that need access to the current view state details class AbstractViewStateInterface { @@ -31,9 +33,7 @@ public: /// copies the current view frustum for rendering the view state virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const = 0; - virtual void copyViewFrustum(ViewFrustum& viewOut) const = 0; - virtual void copySecondaryViewFrustum(ViewFrustum& viewOut) const = 0; - virtual bool hasSecondaryViewFrustum() const = 0; + virtual const ConicalViewFrustums& getConicalViews() const = 0; virtual QThread* getMainThread() = 0; diff --git a/libraries/shared/src/NumericalConstants.h b/libraries/shared/src/NumericalConstants.h index e2d2409d56..4c24a73226 100644 --- a/libraries/shared/src/NumericalConstants.h +++ b/libraries/shared/src/NumericalConstants.h @@ -48,6 +48,8 @@ const int BYTES_PER_KILOBYTE = 1000; const int BYTES_PER_KILOBIT = BYTES_PER_KILOBYTE / BITS_IN_BYTE; const int KILO_PER_MEGA = 1000; +const float SQRT_THREE = 1.73205080f; + #define KB_TO_BYTES_SHIFT 10 #define MB_TO_BYTES_SHIFT 20 #define GB_TO_BYTES_SHIFT 30 diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index ba15222611..34ec074d45 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -15,7 +15,7 @@ #include #include "NumericalConstants.h" -#include "ViewFrustum.h" +#include "shared/ConicalViewFrustum.h" /* PrioritySortUtil is a helper for sorting 3D things relative to a ViewFrustum. To use: @@ -84,12 +84,12 @@ namespace PrioritySortUtil { class PriorityQueue { public: PriorityQueue() = delete; - PriorityQueue(const ViewFrustums& views) : _views(views) { } - PriorityQueue(const ViewFrustums& views, float angularWeight, float centerWeight, float ageWeight) + PriorityQueue(const ConicalViewFrustums& views) : _views(views) { } + PriorityQueue(const ConicalViewFrustums& views, float angularWeight, float centerWeight, float ageWeight) : _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight) { } - void setViews(const ViewFrustums& views) { _views = views; } + void setViews(const ConicalViewFrustums& views) { _views = views; } void setWeights(float angularWeight, float centerWeight, float ageWeight) { _angularWeight = angularWeight; @@ -118,7 +118,7 @@ namespace PrioritySortUtil { return priority; } - float computePriority(const ViewFrustum& view, const T& thing) const { + float computePriority(const ConicalViewFrustum& view, const T& thing) const { // priority = weighted linear combination of multiple values: // (a) angular size // (b) proximity to center of view @@ -143,8 +143,8 @@ namespace PrioritySortUtil { + _ageWeight * cosineAngleFactor * age; // decrement priority of things outside keyhole - if (distance - radius > view.getCenterRadius()) { - if (!view.sphereIntersectsFrustum(position, radius)) { + if (distance - radius > view.getRadius()) { + if (!view.intersects(offset, distance, radius)) { constexpr float OUT_OF_VIEW_PENALTY = -10.0f; priority += OUT_OF_VIEW_PENALTY; } @@ -152,7 +152,7 @@ namespace PrioritySortUtil { return priority; } - ViewFrustums _views; + ConicalViewFrustums _views; std::priority_queue _queue; float _angularWeight { DEFAULT_ANGULAR_COEF }; float _centerWeight { DEFAULT_CENTER_COEF }; diff --git a/libraries/shared/src/ViewFrustum.cpp b/libraries/shared/src/ViewFrustum.cpp index c89a9fbd60..3aa70b0897 100644 --- a/libraries/shared/src/ViewFrustum.cpp +++ b/libraries/shared/src/ViewFrustum.cpp @@ -138,69 +138,6 @@ const char* ViewFrustum::debugPlaneName (int plane) const { return "Unknown"; } -int ViewFrustum::fromByteArray(const QByteArray& input) { - - // From the wire! - glm::vec3 cameraPosition; - glm::quat cameraOrientation; - float cameraCenterRadius; - float cameraFov; - float cameraAspectRatio; - float cameraNearClip; - float cameraFarClip; - - const unsigned char* startPosition = reinterpret_cast(input.constData()); - const unsigned char* sourceBuffer = startPosition; - - // camera details - memcpy(&cameraPosition, sourceBuffer, sizeof(cameraPosition)); - sourceBuffer += sizeof(cameraPosition); - sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, cameraOrientation); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*)sourceBuffer, &cameraFov); - sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, cameraAspectRatio); - sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer, cameraNearClip); - sourceBuffer += unpackClipValueFromTwoByte(sourceBuffer, cameraFarClip); - memcpy(&cameraCenterRadius, sourceBuffer, sizeof(cameraCenterRadius)); - sourceBuffer += sizeof(cameraCenterRadius); - - setPosition(cameraPosition); - setOrientation(cameraOrientation); - setCenterRadius(cameraCenterRadius); - - // Also make sure it's got the correct lens details from the camera - if (0.0f != cameraAspectRatio && - 0.0f != cameraNearClip && - 0.0f != cameraFarClip && - cameraNearClip != cameraFarClip) { - - setProjection(cameraFov, cameraAspectRatio, cameraNearClip, cameraFarClip); - calculate(); - } - - return sourceBuffer - startPosition; -} - - -QByteArray ViewFrustum::toByteArray() { - static const int LARGE_ENOUGH = 1024; - QByteArray viewFrustumDataByteArray(LARGE_ENOUGH, 0); - unsigned char* destinationBuffer = reinterpret_cast(viewFrustumDataByteArray.data()); - unsigned char* startPosition = destinationBuffer; - - // camera details - memcpy(destinationBuffer, &_position, sizeof(_position)); - destinationBuffer += sizeof(_position); - destinationBuffer += packOrientationQuatToBytes(destinationBuffer, _orientation); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _fieldOfView); - destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _aspectRatio); - destinationBuffer += packClipValueToTwoByte(destinationBuffer, _nearClip); - destinationBuffer += packClipValueToTwoByte(destinationBuffer, _farClip); - memcpy(destinationBuffer, &_centerSphereRadius, sizeof(_centerSphereRadius)); - destinationBuffer += sizeof(_centerSphereRadius); - - return viewFrustumDataByteArray.left(destinationBuffer - startPosition); -} - ViewFrustum::intersection ViewFrustum::calculateCubeFrustumIntersection(const AACube& cube) const { // only check against frustum ViewFrustum::intersection result = INSIDE; diff --git a/libraries/shared/src/ViewFrustum.h b/libraries/shared/src/ViewFrustum.h index 128a717df8..eada65468d 100644 --- a/libraries/shared/src/ViewFrustum.h +++ b/libraries/shared/src/ViewFrustum.h @@ -147,9 +147,6 @@ public: void invalidate(); // causes all reasonable intersection tests to fail - QByteArray toByteArray(); - int fromByteArray(const QByteArray& input); - private: glm::mat4 _view; glm::mat4 _projection; diff --git a/libraries/shared/src/shared/ConicalViewFrustum.cpp b/libraries/shared/src/shared/ConicalViewFrustum.cpp index 8538543da6..2ef096e3a8 100644 --- a/libraries/shared/src/shared/ConicalViewFrustum.cpp +++ b/libraries/shared/src/shared/ConicalViewFrustum.cpp @@ -11,6 +11,8 @@ #include "ConicalViewFrustum.h" + +#include "../NumericalConstants.h" #include "../ViewFrustum.h" void ConicalViewFrustum::set(const ViewFrustum& viewFrustum) { @@ -45,13 +47,46 @@ bool ConicalViewFrustum::isVerySimilar(const ConicalViewFrustum& other) const { const float MIN_RELATIVE_ERROR = 0.01f; // 1% return glm::distance2(_position, other._position) < MIN_POSITION_SLOP_SQUARED && - angleBetween(_direction, other._direction) < MIN_ANGLE_BETWEEN && - closeEnough(_angle, other._angle, MIN_RELATIVE_ERROR) && - closeEnough(_farClip, other._farClip, MIN_RELATIVE_ERROR) && - closeEnough(_radius, other._radius, MIN_RELATIVE_ERROR); + angleBetween(_direction, other._direction) < MIN_ANGLE_BETWEEN && + closeEnough(_angle, other._angle, MIN_RELATIVE_ERROR) && + closeEnough(_farClip, other._farClip, MIN_RELATIVE_ERROR) && + closeEnough(_radius, other._radius, MIN_RELATIVE_ERROR); } -bool ConicalViewFrustum::intersects(const glm::vec3& position, float distance, float radius) const { +bool ConicalViewFrustum::intersects(const AACube& cube) const { + auto radius = 0.5f * SQRT_THREE * cube.getScale(); // radius of bounding sphere + auto position = cube.calcCenter() - _position; // position of bounding sphere in view-frame + float distance = glm::length(position); + + return intersects(position, distance, radius); +} + +bool ConicalViewFrustum::intersects(const AABox& box) const { + auto radius = 0.5f * glm::length(box.getScale()); // radius of bounding sphere + auto position = box.calcCenter() - _position; // position of bounding sphere in view-frame + float distance = glm::length(position); + + return intersects(position, distance, radius); +} + +bool ConicalViewFrustum::getAngularSize(const AACube& cube) const { + auto radius = 0.5f * SQRT_THREE * cube.getScale(); // radius of bounding sphere + auto position = cube.calcCenter() - _position; // position of bounding sphere in view-frame + float distance = glm::length(position); + + return getAngularSize(distance, radius); +} + +bool ConicalViewFrustum::getAngularSize(const AABox& box) const { + auto radius = 0.5f * glm::length(box.getScale()); // radius of bounding sphere + auto position = box.calcCenter() - _position; // position of bounding sphere in view-frame + float distance = glm::length(position); + + return getAngularSize(distance, radius); +} + + +bool ConicalViewFrustum::intersects(const glm::vec3& relativePosition, float distance, float radius) const { if (distance < _radius + radius) { // Inside keyhole radius return true; @@ -68,7 +103,7 @@ bool ConicalViewFrustum::intersects(const glm::vec3& position, float distance, f // The math here is left as an exercise for the reader with the following hints: // (1) We actually check the dot product of the cube's local position rather than the angle and // (2) we take advantage of this trig identity: cos(A+B) = cos(A)*cos(B) - sin(A)*sin(B) - return glm::dot(position, _direction) > + return glm::dot(relativePosition, _direction) > sqrtf(distance * distance - radius * radius) * _cosAngle - radius * _sinAngle; } diff --git a/libraries/shared/src/shared/ConicalViewFrustum.h b/libraries/shared/src/shared/ConicalViewFrustum.h index 3cadedda9d..dc372d560e 100644 --- a/libraries/shared/src/shared/ConicalViewFrustum.h +++ b/libraries/shared/src/shared/ConicalViewFrustum.h @@ -17,6 +17,7 @@ #include class AACube; +class AABox; class ViewFrustum; using ViewFrustums = std::vector; @@ -42,7 +43,12 @@ public: bool isVerySimilar(const ConicalViewFrustum& other) const; - bool intersects(const glm::vec3& position, float distance, float radius) const; + bool intersects(const AACube& cube) const; + bool intersects(const AABox& box) const; + bool getAngularSize(const AACube& cube) const; + bool getAngularSize(const AABox& box) const; + + bool intersects(const glm::vec3& relativePosition, float distance, float radius) const; bool getAngularSize(float distance, float radius) const; int serialize(unsigned char* destinationBuffer) const; diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 8c17d7c5c2..2e72d9cead 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -441,14 +442,9 @@ protected: viewOut = _viewFrustum; } - void copyViewFrustum(ViewFrustum& viewOut) const override { - viewOut = _viewFrustum; - } - - void copySecondaryViewFrustum(ViewFrustum& viewOut) const override {} - - bool hasSecondaryViewFrustum() const override { - return false; + const ConicalViewFrustums& getConicalViews() const override { + assert(false); + return ConicalViewFrustums(); } QThread* getMainThread() override { From d7e9fdc6a42b0c2940399a6103d80e5d52f5d1e6 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 1 May 2018 18:19:25 -0700 Subject: [PATCH 27/36] Bump Avatar Query packet version --- libraries/networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 123e11b7c5..d6ab7d0f9c 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::Ping: return static_cast(PingVersion::IncludeConnectionID); case PacketType::AvatarQuery: - return static_cast(AvatarQueryVersion::SendMultipleFrustums); + return static_cast(AvatarQueryVersion::ConicalFrustums); default: return 20; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 1bedfdf3e6..2252b09ae5 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -330,7 +330,8 @@ enum class PingVersion : PacketVersion { }; enum class AvatarQueryVersion : PacketVersion { - SendMultipleFrustums = 21 + SendMultipleFrustums = 21, + ConicalFrustums = 22 }; #endif // hifi_PacketHeaders_h From d87cd2af6e979f3010bb21a6ac4992a921233238 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 1 May 2018 18:23:00 -0700 Subject: [PATCH 28/36] Update avatar query names --- assignment-client/src/Agent.cpp | 14 +++++++------- assignment-client/src/Agent.h | 4 ++-- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index da811b8af5..42924a8487 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -548,18 +548,18 @@ void Agent::setIsAvatar(bool isAvatar) { if (_isAvatar && !_avatarIdentityTimer) { // set up the avatar timers _avatarIdentityTimer = new QTimer(this); - _avatarViewTimer = new QTimer(this); + _avatarQueryTimer = new QTimer(this); // connect our slot connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket); - connect(_avatarViewTimer, &QTimer::timeout, this, &Agent::sendAvatarViewFrustum); + connect(_avatarQueryTimer, &QTimer::timeout, this, &Agent::queryAvatars); static const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000; static const int AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS = 1000; // start the timers _avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets - _avatarViewTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS); + _avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS); // tell the avatarAudioTimer to start ticking QMetaObject::invokeMethod(&_avatarAudioTimer, "start"); @@ -572,9 +572,9 @@ void Agent::setIsAvatar(bool isAvatar) { delete _avatarIdentityTimer; _avatarIdentityTimer = nullptr; - _avatarViewTimer->stop(); - delete _avatarViewTimer; - _avatarViewTimer = nullptr; + _avatarQueryTimer->stop(); + delete _avatarQueryTimer; + _avatarQueryTimer = nullptr; // The avatar mixer never times out a connection (e.g., based on identity or data packets) // but rather keeps avatars in its list as long as "connected". As a result, clients timeout @@ -607,7 +607,7 @@ void Agent::sendAvatarIdentityPacket() { } } -void Agent::sendAvatarViewFrustum() { +void Agent::queryAvatars() { auto scriptedAvatar = DependencyManager::get(); ViewFrustum view; diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index d144f0bc01..0cdc9e0029 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -97,7 +97,7 @@ private: void setAvatarSound(SharedSoundPointer avatarSound) { _avatarSound = avatarSound; } void sendAvatarIdentityPacket(); - void sendAvatarViewFrustum(); + void queryAvatars(); QString _scriptContents; QTimer* _scriptRequestTimeout { nullptr }; @@ -107,7 +107,7 @@ private: int _numAvatarSoundSentBytes = 0; bool _isAvatar = false; QTimer* _avatarIdentityTimer = nullptr; - QTimer* _avatarViewTimer = nullptr; + QTimer* _avatarQueryTimer = nullptr; QHash _outgoingScriptAudioSequenceNumbers; AudioGate _audioGate; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d14af685f0..f9d048b6ac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5682,7 +5682,7 @@ void Application::update(float deltaTime) { if (DependencyManager::get()->shouldRenderEntities()) { queryOctree(NodeType::EntityServer, PacketType::EntityQuery); } - sendAvatarViewFrustum(); + queryAvatars(); _lastQueriedViews = _conicalViews; _lastQueriedTime = now; @@ -5857,7 +5857,7 @@ void Application::update(float deltaTime) { } } -void Application::sendAvatarViewFrustum() { +void Application::queryAvatars() { auto avatarPacket = NLPacket::create(PacketType::AvatarQuery); auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); unsigned char* bufferStart = destinationBuffer; diff --git a/interface/src/Application.h b/interface/src/Application.h index 6d749f9458..4a9c293237 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -492,9 +492,9 @@ private: void updateDialogs(float deltaTime) const; void queryOctree(NodeType_t serverType, PacketType packetType); + void queryAvatars(); int sendNackPackets(); - void sendAvatarViewFrustum(); std::shared_ptr getMyAvatar() const; From 487a63025f0681d52f032e85fd4530468392d6e0 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 1 May 2018 19:11:00 -0700 Subject: [PATCH 29/36] Fix warning --- assignment-client/src/avatars/AvatarMixerClientData.cpp | 2 +- assignment-client/src/avatars/AvatarMixerClientData.h | 2 +- interface/src/Application.cpp | 2 +- libraries/octree/src/OctreeQuery.cpp | 2 +- tests/render-perf/src/main.cpp | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index aa93fc9e08..d5a8b37742 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -126,7 +126,7 @@ void AvatarMixerClientData::removeFromRadiusIgnoringSet(SharedNodePointer self, } } -void AvatarMixerClientData::readViewFrustumPacket(QByteArray message) { +void AvatarMixerClientData::readViewFrustumPacket(const QByteArray& message) { _currentViewFrustums.clear(); auto sourceBuffer = reinterpret_cast(message.constData()); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index f3b2b587ee..e038e81505 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -98,7 +98,7 @@ public: void removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other); void ignoreOther(SharedNodePointer self, SharedNodePointer other); - void readViewFrustumPacket(QByteArray message); + void readViewFrustumPacket(const QByteArray& message); bool otherAvatarInView(const AABox& otherAvatarBox); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f9d048b6ac..d3c75219c5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5862,7 +5862,7 @@ void Application::queryAvatars() { auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); unsigned char* bufferStart = destinationBuffer; - uint8_t numFrustums = _conicalViews.size(); + uint8_t numFrustums = (uint8_t)_conicalViews.size(); memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); destinationBuffer += sizeof(numFrustums); diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 072774f0f5..3f730d4458 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -35,7 +35,7 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(_connectionID); // Number of frustums - uint8_t numFrustums = _conicalViews.size(); + uint8_t numFrustums = (uint8_t)_conicalViews.size(); memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); destinationBuffer += sizeof(numFrustums); diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 2e72d9cead..33aea6dcc9 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -443,8 +443,7 @@ protected: } const ConicalViewFrustums& getConicalViews() const override { - assert(false); - return ConicalViewFrustums(); + return _view; } QThread* getMainThread() override { @@ -1122,6 +1121,7 @@ private: graphics::LightPointer _globalLight { std::make_shared() }; bool _ready { false }; EntitySimulationPointer _entitySimulation; + ConicalViewFrustums _view; QStringList _commands; QString _commandPath; From 53fe0bc616c36ebece838e0e00cf84575addfcf7 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 4 May 2018 14:08:21 -0700 Subject: [PATCH 30/36] MS14699: Prevent Wallet passcode from being sticky in certain cases --- .../qml/hifi/commerce/wallet/PassphraseModal.qml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 1cada9789b..c4abd40d2a 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -47,6 +47,13 @@ Item { onWalletAuthenticatedStatusResult: { submitPassphraseInputButton.enabled = true; + + // It's not possible to auth with a blank passphrase, + // so bail early if we get this signal without anything in the passphrase field + if (passphraseField.text === "") { + return; + } + if (!isAuthenticated) { errorText.text = "Authentication failed - please try again."; passphraseField.error = true; @@ -211,6 +218,10 @@ Item { error = false; focus = true; forceActiveFocus(); + } else { + showPassphrase.checked = false; + passphraseField.text = ""; + error = false; } } From d4a6e845cdb32a37f287bf4d11df58f77fa932d1 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 4 May 2018 18:37:22 -0300 Subject: [PATCH 31/36] Android - Search - Code style fixes --- .../highfidelity/hifiinterface/HomeActivity.java | 2 +- .../provider/UserStoryDomainProvider.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 759665b660..803483d724 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -120,7 +120,7 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On @Override public void afterTextChanged(Editable editable) { mDomainAdapter.loadDomains(editable.toString()); - if(editable.length()>0) { + if (editable.length() > 0) { mSearchIconView.setVisibility(View.GONE); mClearSearch.setVisibility(View.VISIBLE); } else { diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java index 50202234e9..1e29734243 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/provider/UserStoryDomainProvider.java @@ -109,15 +109,17 @@ public class UserStoryDomainProvider implements DomainProvider { } private boolean matches(UserStory story) { - if (mWords.length<=0) return true; - - boolean res = true; - for (String word: mWords) { - res = res && story.searchText().contains(word); - if (!res) break; + if (mWords.length <= 0) { + return true; } - return res; + for (String word : mWords) { + if (!story.searchText().contains(word)) { + return false; + } + } + + return true; } private void addToSuggestions(UserStory story) { From b04c5bd0db04688dfa965fe3aa90d79ab2bbf1fa Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 4 May 2018 14:43:16 -0700 Subject: [PATCH 32/36] CR --- interface/src/Application.cpp | 16 ++++++++-------- interface/src/Application.h | 8 ++++++-- libraries/entities/src/EntityPriorityQueue.h | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d3c75219c5..0d8ab13a9f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -967,7 +967,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _entitySimulation(new PhysicalEntitySimulation()), _physicsEngine(new PhysicsEngine(Vectors::ZERO)), _entityClipboard(new EntityTree()), - _lastQueriedTime(usecTimestampNow()), _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), _hmdTabletScale("hmdTabletScale", DEFAULT_HMD_TABLET_SCALE_PERCENT), @@ -5084,7 +5083,7 @@ void Application::reloadResourceCaches() { resetPhysicsReadyInformation(); // Query the octree to refresh everything in view - _lastQueriedTime = 0; + _queryExpiry = SteadyClock::now(); _octreeQuery.incrementConnectionID(); queryOctree(NodeType::EntityServer, PacketType::EntityQuery); @@ -5660,9 +5659,6 @@ void Application::update(float deltaTime) { PROFILE_RANGE_EX(app, "QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount()); PerformanceTimer perfTimer("queryOctree"); QMutexLocker viewLocker(&_viewMutex); - quint64 sinceLastQuery = now - _lastQueriedTime; - const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; - bool queryIsDue = sinceLastQuery > TOO_LONG_SINCE_LAST_QUERY; bool viewIsDifferentEnough = false; if (_conicalViews.size() == _lastQueriedViews.size()) { @@ -5678,14 +5674,16 @@ void Application::update(float deltaTime) { // if it's been a while since our last query or the view has significantly changed then send a query, otherwise suppress it - if (queryIsDue || viewIsDifferentEnough) { + static const std::chrono::seconds MIN_PERIOD_BETWEEN_QUERIES { 3 }; + auto now = SteadyClock::now(); + if (now > _queryExpiry || viewIsDifferentEnough) { if (DependencyManager::get()->shouldRenderEntities()) { queryOctree(NodeType::EntityServer, PacketType::EntityQuery); } queryAvatars(); _lastQueriedViews = _conicalViews; - _lastQueriedTime = now; + _queryExpiry = now + MIN_PERIOD_BETWEEN_QUERIES; } } @@ -6142,7 +6140,7 @@ void Application::nodeActivated(SharedNodePointer node) { // If we get a new EntityServer activated, reset lastQueried time // so we will do a proper query during update if (node->getType() == NodeType::EntityServer) { - _lastQueriedTime = 0; + _queryExpiry = SteadyClock::now(); _octreeQuery.incrementConnectionID(); } @@ -6151,6 +6149,8 @@ void Application::nodeActivated(SharedNodePointer node) { } if (node->getType() == NodeType::AvatarMixer) { + _queryExpiry = SteadyClock::now(); + // new avatar mixer, send off our identity packet on next update loop // Reset skeletonModelUrl if the last server modified our choice. // Override the avatar url (but not model name) here too. diff --git a/interface/src/Application.h b/interface/src/Application.h index 4a9c293237..654b5c797b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -111,7 +111,8 @@ class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler, - public PluginContainer { + public PluginContainer +{ Q_OBJECT // TODO? Get rid of those @@ -579,7 +580,10 @@ private: ConicalViewFrustums _conicalViews; ConicalViewFrustums _lastQueriedViews; // last views used to query servers - quint64 _lastQueriedTime; + + using SteadyClock = std::chrono::steady_clock; + using TimePoint = SteadyClock::time_point; + TimePoint _queryExpiry; OctreeQuery _octreeQuery { true }; // NodeData derived class for querying octee cells from octree servers diff --git a/libraries/entities/src/EntityPriorityQueue.h b/libraries/entities/src/EntityPriorityQueue.h index 354cd70af3..339676d237 100644 --- a/libraries/entities/src/EntityPriorityQueue.h +++ b/libraries/entities/src/EntityPriorityQueue.h @@ -20,8 +20,8 @@ // PrioritizedEntity is a placeholder in a sorted queue. class PrioritizedEntity { public: - static constexpr float DO_NOT_SEND { -1.0e-6f }; - static constexpr float FORCE_REMOVE { -1.0e-5f }; + static constexpr float DO_NOT_SEND { -1.0e6f }; + static constexpr float FORCE_REMOVE { -1.0e5f }; static constexpr float WHEN_IN_DOUBT_PRIORITY { 1.0f }; PrioritizedEntity(EntityItemPointer entity, float priority, bool forceRemove = false) : _weakEntity(entity), _rawEntityPointer(entity.get()), _priority(priority), _forceRemove(forceRemove) {} From ad60a791803c41ddfac08aef31d7f0ed3c144d46 Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 4 May 2018 14:43:28 -0700 Subject: [PATCH 33/36] Fix for android builds --- interface/src/Application.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0d8ab13a9f..0a76c8f475 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5226,9 +5226,8 @@ void Application::updateSecondaryCameraViewFrustum() { auto renderConfig = _renderEngine->getConfiguration(); assert(renderConfig); auto camera = dynamic_cast(renderConfig->getConfig("SecondaryCamera")); - assert(camera); - if (!camera->isEnabled()) { + if (!camera || !camera->isEnabled()) { return; } From 8c96d2be3c60a70ce63708f1012f08a01e6cee35 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 4 May 2018 18:44:07 -0300 Subject: [PATCH 34/36] Patch for secondary camera assert error on Android --- interface/src/Application.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b55637ea76..cb25ecc302 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5231,9 +5231,8 @@ void Application::updateSecondaryCameraViewFrustum() { auto renderConfig = _renderEngine->getConfiguration(); assert(renderConfig); auto camera = dynamic_cast(renderConfig->getConfig("SecondaryCamera")); - assert(camera); - if (!camera->isEnabled()) { + if (!camera || !camera->isEnabled()) { _hasSecondaryViewFrustum = false; return; } From a363041482adb655cb19423361931f7252ee7566 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 4 May 2018 18:46:46 -0300 Subject: [PATCH 35/36] Material precision on GL ES fix not needed anymore --- libraries/graphics/src/graphics/Material.slh | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index 76ce336406..ecf3c18a0e 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -13,9 +13,6 @@ // The material values (at least the material key) must be precisely bitwise accurate // to what is provided by the uniform buffer, or the material key has the wrong bits -#ifdef GL_ES -precision highp float; -#endif struct Material { PRECISIONQ vec4 _emissiveOpacity; From de00f680fa725eafb03e38fb199f2fa5e8388494 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 4 May 2018 18:51:02 -0300 Subject: [PATCH 36/36] Android - Search - Domains local file not needed anymore --- android/app/src/main/assets/hifi_domains.json | 24 ------------- .../hifiinterface/view/DomainAdapter.java | 34 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 android/app/src/main/assets/hifi_domains.json diff --git a/android/app/src/main/assets/hifi_domains.json b/android/app/src/main/assets/hifi_domains.json deleted file mode 100644 index a63ef7b6aa..0000000000 --- a/android/app/src/main/assets/hifi_domains.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "hifi_domains" : [ - { - "name": "Your last location", - "url": "", - "thumbnail": "" - }, - { - "name": "dev-mobile-master", - "url": "hifi://dev-mobile-master", - "thumbnail": "" - }, - { - "name": "dev-mobile", - "url": "hifi://dev-mobile", - "thumbnail": "" - }, - { - "name": "dev-welcome", - "url": "hifi://dev-welcome", - "thumbnail": "" - } - ] -} \ No newline at end of file diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 4c0f54e354..4f6394636f 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -30,7 +30,6 @@ import io.highfidelity.hifiinterface.provider.UserStoryDomainProvider; */ public class DomainAdapter extends RecyclerView.Adapter { - private static final java.lang.String DOMAINS_FILE = "hifi_domains.json"; private static final String TAG = "HiFi Interface"; private Context mContext; private LayoutInflater mInflater; @@ -76,39 +75,6 @@ public class DomainAdapter extends RecyclerView.Adapter domains = new ArrayList<>(); - for (int i = 0; i < hifiDomains.length(); i++) { - JSONObject jDomain = hifiDomains.getJSONObject(i); - - String domainName = jDomain.getString("name"); - String domainUrl = jDomain.getString("url"); - String domainThumb = jDomain.getString("thumbnail"); - - domains.add(new Domain(domainName, domainUrl, domainThumb)); - } - mDomains = domains.toArray(mDomains); - } catch (IOException e) { - Log.e(TAG, "Error loading domains from local file", e); - } catch (JSONException e) { - Log.e(TAG, "Error loading domains from local file", e); - } - } - - public String loadJSONFromAsset() throws IOException { - String json = null; - InputStream is = mContext.getAssets().open(DOMAINS_FILE); - int size = is.available(); - byte[] buffer = new byte[size]; - is.read(buffer); - is.close(); - json = new String(buffer, "UTF-8"); - return json; - } - @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = mInflater.inflate(R.layout.domain_view, parent, false);