Merge branch 'master' of https://github.com/highfidelity/hifi into fixGrabWebSurface-case-16192

This commit is contained in:
Wayne Chen 2018-07-17 11:54:15 -07:00
commit 2c16c6579f
57 changed files with 354 additions and 209 deletions

View file

@ -4,6 +4,7 @@ import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
@ -32,6 +33,7 @@ public class HomeFragment extends Fragment {
private OnHomeInteractionListener mListener;
private SwipeRefreshLayout mSwipeRefreshLayout;
public native String nativeGetLastLocation();
@ -57,6 +59,7 @@ public class HomeFragment extends Fragment {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
searchNoResultsView = rootView.findViewById(R.id.searchNoResultsView);
mSwipeRefreshLayout = rootView.findViewById(R.id.swipeRefreshLayout);
mDomainsView = rootView.findViewById(R.id.rvDomains);
int numberOfColumns = 1;
@ -76,12 +79,14 @@ public class HomeFragment extends Fragment {
searchNoResultsView.setText(R.string.search_no_results);
searchNoResultsView.setVisibility(View.VISIBLE);
mDomainsView.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onNonEmptyAdapter() {
searchNoResultsView.setVisibility(View.GONE);
mDomainsView.setVisibility(View.VISIBLE);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
@ -104,7 +109,7 @@ public class HomeFragment extends Fragment {
@Override
public void afterTextChanged(Editable editable) {
mDomainAdapter.loadDomains(editable.toString());
mDomainAdapter.loadDomains(editable.toString(), false);
if (editable.length() > 0) {
mSearchIconView.setVisibility(View.GONE);
mClearSearch.setVisibility(View.VISIBLE);
@ -130,6 +135,13 @@ public class HomeFragment extends Fragment {
mClearSearch.setOnClickListener(view -> onSearchClear(view));
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mDomainAdapter.loadDomains(mSearchView.getText().toString(), true);
}
});
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
return rootView;

View file

@ -10,7 +10,7 @@ import io.highfidelity.hifiinterface.view.DomainAdapter;
public interface DomainProvider {
void retrieve(String filterText, DomainCallback domainCallback);
void retrieve(String filterText, DomainCallback domainCallback, boolean forceRefresh);
interface DomainCallback {
void retrieveOk(List<DomainAdapter.Domain> domain);

View file

@ -49,8 +49,8 @@ public class UserStoryDomainProvider implements DomainProvider {
}
@Override
public synchronized void retrieve(String filterText, DomainCallback domainCallback) {
if (!startedToGetFromAPI) {
public synchronized void retrieve(String filterText, DomainCallback domainCallback, boolean forceRefresh) {
if (!startedToGetFromAPI || forceRefresh) {
startedToGetFromAPI = true;
fillDestinations(filterText, domainCallback);
} else {
@ -72,6 +72,7 @@ public class UserStoryDomainProvider implements DomainProvider {
allStories.clear();
getUserStoryPage(1, allStories, null,
ex -> {
suggestions.clear();
allStories.forEach(userStory -> {
if (taggedStoriesIds.contains(userStory.id)) {
userStory.tagFound = true;

View file

@ -42,14 +42,14 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
mProtocol = protocol;
mLastLocation = lastLocation;
domainProvider = new UserStoryDomainProvider(mProtocol);
loadDomains("");
loadDomains("", true);
}
public void setListener(AdapterListener adapterListener) {
mAdapterListener = adapterListener;
}
public void loadDomains(String filterText) {
public void loadDomains(String filterText, boolean forceRefresh) {
domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() {
@Override
public void retrieveOk(List<Domain> domain) {
@ -76,7 +76,7 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
Log.e("DOMAINS", message, e);
if (mAdapterListener != null) mAdapterListener.onError(e, message);
}
});
}, forceRefresh);
}
private void overrideDefaultThumbnails(List<Domain> domain) {

View file

@ -63,13 +63,18 @@
android:visibility="gone"
/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvDomains"
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
app:layout_constraintTop_toBottomOf="@id/searchView"
app:layout_constraintBottom_toBottomOf="@id/contentHomeRoot"
app:layout_constraintStart_toStartOf="@id/contentHomeRoot"
app:layout_constraintEnd_toEndOf="@id/contentHomeRoot"
android:layout_width="0dp"
android:layout_height="0dp" />
android:layout_height="0dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvDomains"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME GifCreator)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/GifCreator.zip
URL https://public.highfidelity.com/dependencies/GifCreator.zip
URL_MD5 8ac8ef5196f47c658dce784df5ecdb70
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -17,7 +17,7 @@ if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.26.0_public.zip
URL https://public.highfidelity.com/dependencies/ovr_sdk_win_1.26.0_public.zip
URL_MD5 06804ff9727b910dcd04a37c800053b5
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
@ -38,7 +38,7 @@ elseif(APPLE)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://static.oculus.com/sdk-downloads/ovr_sdk_macos_0.5.0.1.tar.gz
URL https://public.highfidelity.com/dependencies/ovr_sdk_macos_0.5.0.1.tar.gz
URL_MD5 0a0785a04fb285f64f62267388344ad6
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -9,7 +9,7 @@ if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/OVRPlatformSDK_v1.10.0.zip
URL https://public.highfidelity.com/dependencies/OVRPlatformSDK_v1.10.0.zip
URL_MD5 e6c8264af16d904e6506acd5172fa0a9
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -5,7 +5,7 @@ include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
#URL https://github.com/boostorg/config/archive/boost-1.58.0.zip
URL http://hifi-public.s3.amazonaws.com/dependencies/config-boost-1.58.0.zip
URL https://public.highfidelity.com/dependencies/config-boost-1.58.0.zip
URL_MD5 42fa673bae2b7645a22736445e80eb8d
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -17,7 +17,7 @@ include(ExternalProject)
if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.88.tgz
URL https://public.highfidelity.com/dependencies/bullet-2.88.tgz
URL_MD5 0a6876607ebe83e227427215f15946fd
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0 -DUSE_DX11=0
LOG_DOWNLOAD 1
@ -28,7 +28,7 @@ if (WIN32)
else ()
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.88.tgz
URL https://public.highfidelity.com/dependencies/bullet-2.88.tgz
URL_MD5 0a6876607ebe83e227427215f15946fd
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_BULLET3=0 -DBUILD_OPENGL3_DEMOS=0 -DBUILD_BULLET2_DEMOS=0 -DBUILD_UNIT_TESTS=0 -DUSE_GLUT=0
LOG_DOWNLOAD 1

View file

@ -6,7 +6,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://public.highfidelity.com/dependencies/crashpad_062317.1.zip
URL https://public.highfidelity.com/dependencies/crashpad_062317.1.zip
URL_MD5 9c84b77f5f23daf939da1371825ed2b1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@ -25,7 +25,7 @@ if (WIN32)
elseif (APPLE)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://public.highfidelity.com/dependencies/crashpad_mac_070318.zip
URL https://public.highfidelity.com/dependencies/crashpad_mac_070318.zip
URL_MD5 ba1501dc163591ac2d1be74946967e2a
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -11,7 +11,7 @@ endif ()
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/draco-1.1.0.zip
URL https://public.highfidelity.com/dependencies/draco-1.1.0.zip
URL_MD5 208f8b04c91d5f1c73d731a3ea37c5bb
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
LOG_DOWNLOAD 1

View file

@ -15,7 +15,7 @@ include(ExternalProject)
# that would override CMAKE_CXX_FLAGS
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/etc2comp-patched.zip
URL https://public.highfidelity.com/dependencies/etc2comp-patched.zip
URL_MD5 4c96153eb179acbe619e3d99d3330595
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} ${EXTRA_CMAKE_FLAGS}
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad32es.zip
URL https://public.highfidelity.com/dependencies/glad/glad32es.zip
URL_MD5 6a641d8c49dee4c895fa59315f5682a6
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad41.zip
URL https://public.highfidelity.com/dependencies/glad/glad41.zip
URL_MD5 1324eeec33abe91e67d19ae551ba624d
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1

View file

@ -5,7 +5,7 @@ include(SelectLibraryConfigurations)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/austin/glad/glad45.zip
URL https://public.highfidelity.com/dependencies/glad/glad45.zip
URL_MD5 cfb19b3cb5b2f8f1d1669fb3150e5f05
CONFIGURE_COMMAND CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME gli)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/gli-0.8.1.0.zip
URL https://public.highfidelity.com/dependencies/gli-0.8.1.0.zip
URL_MD5 00c990f59c12bbf367956ef399d6f798
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CONFIGURE_COMMAND ""

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME glm)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/glm-0.9.8.5-patched.zip
URL https://public.highfidelity.com/dependencies/glm-0.9.8.5-patched.zip
URL_MD5 7d39ecc1cea275427534c3cfd6dd63f0
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTERNAL_ARGS}

View file

@ -6,16 +6,16 @@ set(EXTERNAL_NAME hifiAudioCodec)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-win-2.0.zip)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-win-2.0.zip)
set(DOWNLOAD_MD5 9199d4dbd6b16bed736b235efe980e67)
elseif (APPLE)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-mac-2.0.zip)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-mac-2.0.zip)
set(DOWNLOAD_MD5 21649881e7d5dc94f922179be96f76ba)
elseif (ANDROID)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-android-2.0.zip)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-android-2.0.zip)
set(DOWNLOAD_MD5 aef2a852600d498d58aa586668191683)
elseif (UNIX)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux-2.0.zip)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-linux-2.0.zip)
set(DOWNLOAD_MD5 67fb7755f9bcafb98a9fceea53bc7481)
else()
return()

View file

@ -4,7 +4,7 @@ set(EXTERNAL_NAME neuron)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(NEURON_URL "https://s3.amazonaws.com/hifi-public/dependencies/neuron_datareader_b.12.2.zip")
set(NEURON_URL "https://public.highfidelity.com/dependencies/neuron_datareader_b.12.2.zip")
set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca")
ExternalProject_Add(${EXTERNAL_NAME}

View file

@ -8,7 +8,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip
URL https://public.highfidelity.com/dependencies/nvtt-win-2.1.0.hifi.zip
URL_MD5 10da01cf601f88f6dc12a6bc13c89136
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@ -29,7 +29,7 @@ else ()
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi-83462e4.zip
URL https://public.highfidelity.com/dependencies/nvidia-texture-tools-2.1.0.hifi-83462e4.zip
URL_MD5 602776e08515b54bfa1b8dc455003f0f
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
LOG_DOWNLOAD 1

View file

@ -7,7 +7,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://github.com/ValveSoftware/openvr/archive/v1.0.6.zip
URL https://public.highfidelity.com/dependencies/openvr-1.0.6.zip
URL_MD5 f6892cd3a3078f505d03b4297f5a1951
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -3,7 +3,7 @@ set(EXTERNAL_NAME polyvox)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/polyvox-master-2015-7-15.zip
URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip
URL_MD5 9ec6323b87e849ae36e562ae1c7494a9
CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -13,7 +13,7 @@ endif ()
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/quazip-0.7.3.zip
URL https://public.highfidelity.com/dependencies/quazip-0.7.3.zip
URL_MD5 ed03754d39b9da1775771819b8001d45
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CMAKE_ARGS ${QUAZIP_CMAKE_ARGS}

View file

@ -7,7 +7,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-devel-2.0.3-VC.zip
URL https://public.highfidelity.com/dependencies/SDL2-devel-2.0.3-VC.zip
URL_MD5 30a333bcbe94bc5016e8799c73e86233
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@ -18,7 +18,8 @@ elseif (APPLE)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3.zip
URL https://public.highfidelity.com/dependencies/SDL2-2.0.3.zip
URL_MD5 55f1eae5142d20db11c844d8d4d6deed
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DVIDEO_OPENGL=OFF
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
LOG_DOWNLOAD 1
@ -49,7 +50,7 @@ else ()
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://www.libsdl.org/release/SDL2-2.0.3.tar.gz
URL https://public.highfidelity.com/dependencies/SDL2-2.0.3.tar.gz
URL_MD5 fe6c61d2e9df9ef570e7e80c6e822537
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
LOG_DOWNLOAD 1

View file

@ -4,15 +4,15 @@ set(EXTERNAL_NAME sixense)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
#set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_062612.zip")
#set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_062612.zip")
#set(SIXENSE_URL_MD5 "10cc8dc470d2ac1244a88cf04bc549cc")
#set(SIXENSE_NEW_LAYOUT 0)
set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip")
set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_071615.zip")
set(SIXENSE_URL_MD5 "752a3901f334124e9cffc2ba4136ef7d")
set(SIXENSE_NEW_LAYOUT 1)
#set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_102215.zip")
#set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_102215.zip")
#set(SIXENSE_URL_MD5 "93c3a6795cce777a0f472b09532935f1")
#set(SIXENSE_NEW_LAYOUT 1)

View file

@ -4,7 +4,7 @@ set(EXTERNAL_NAME steamworks)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(STEAMWORKS_URL "https://s3.amazonaws.com/hifi-public/dependencies/steamworks_sdk_137.zip")
set(STEAMWORKS_URL "https://public.highfidelity.com/dependencies/steamworks_sdk_137.zip")
set(STEAMWORKS_URL_MD5 "95ba9d0e3ddc04f8a8be17d2da806cbb")
ExternalProject_Add(

View file

@ -3,13 +3,13 @@ set(EXTERNAL_NAME tbb)
include(ExternalProject)
if (WIN32)
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb2017_20170604oss_win_slim.zip)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_win_slim.zip)
set(DOWNLOAD_MD5 065934458e3db88397f3d10e7eea536c)
elseif (APPLE)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb2017_20170604oss_mac_slim.tar.gz)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_mac_slim.tar.gz)
set(DOWNLOAD_MD5 62bde626b396f8e1a85c6a8ded1d8105)
else ()
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb2017_20170604oss_lin_slim.tar.gz)
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_lin_slim.tar.gz)
set(DOWNLOAD_MD5 2a5c721f40fa3503ffc12c18dd00011c)
endif ()

View file

@ -7,7 +7,7 @@ endif ()
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/v-hacd-master.zip
URL https://public.highfidelity.com/dependencies/v-hacd-master.zip
URL_MD5 3bfc94f8dd3dfbfe8f4dc088f4820b3e
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build

View file

@ -6,7 +6,7 @@ if (WIN32)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/qtaudio_wasapi10.zip
URL https://public.highfidelity.com/dependencies/qtaudio_wasapi10.zip
URL_MD5 4f40e49715a420fb67b45b9cee19052c
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View file

@ -5,7 +5,8 @@ include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/zlib128.zip
URL https://public.highfidelity.com/dependencies/zlib128.zip
URL_MD5 126f8676442ffbd97884eb4d6f32afb4
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
LOG_DOWNLOAD 1

View file

@ -46,7 +46,6 @@ FocusScope {
hoverEnabled: true
visible: true
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.
textRole: "text"
function previousItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count - 1) % comboBox.count; }
function nextItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count + 1) % comboBox.count; }

View file

@ -1108,7 +1108,7 @@ Rectangle {
function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml
var data = optionalData || nearbyUserModelData, length = data.length;
for (var i = 0; i < length; i++) {
if (data[i].sessionId === sessionId) {
if (data[i].sessionId === sessionId.toString()) {
return i;
}
}
@ -1120,7 +1120,7 @@ Rectangle {
var data = message.params;
var index = -1;
iAmAdmin = Users.canKick;
index = findNearbySessionIndex('', data);
index = findNearbySessionIndex("", data);
if (index !== -1) {
myData = data[index];
data.splice(index, 1);
@ -1197,8 +1197,8 @@ Rectangle {
for (var userId in message.params) {
var audioLevel = message.params[userId][0];
var avgAudioLevel = message.params[userId][1];
// If the userId is 0, we're updating "myData".
if (userId == 0) {
// If the userId is "", we're updating "myData".
if (userId === "") {
myData.audioLevel = audioLevel;
myCard.audioLevel = audioLevel; // Defensive programming
myData.avgAudioLevel = avgAudioLevel;

View file

@ -125,7 +125,6 @@ Rectangle {
id: wearablesCombobox
anchors.left: parent.left
anchors.right: parent.right
comboBox.textRole: "text"
model: ListModel {
function findIndexById(id) {

View file

@ -328,7 +328,15 @@ Item {
item.buttonColor = "#E2334D";
item.buttonClicked = function() {
sendToPurchases({ method: 'flipCard', closeAll: true });
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
sendToPurchases({
method: 'updateItemClicked',
itemId: root.itemId,
itemEdition: root.itemEdition,
upgradeUrl: root.upgradeUrl,
itemHref: root.itemHref,
itemType: root.itemType,
isInstalled: root.isInstalled
});
}
}
}

View file

@ -706,7 +706,23 @@ Rectangle {
}
}
} else if (msg.method === "updateItemClicked") {
sendToScript(msg);
if (msg.itemType === "app" && msg.isInstalled) {
lightboxPopup.titleText = "Uninstall App";
lightboxPopup.bodyText = "The app that you are trying to update is installed.<br><br>" +
"If you proceed, the current version of the app will be uninstalled.";
lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = function() {
Commerce.uninstallApp(msg.itemHref);
sendToScript(msg);
};
lightboxPopup.visible = true;
} else {
sendToScript(msg);
}
} else if (msg.method === "giftAsset") {
sendAsset.assetName = msg.itemName;
sendAsset.assetCertID = msg.certId;

View file

@ -14,6 +14,7 @@
#include <string>
#include <QScriptEngine>
#include <QtCore/QJsonDocument>
#include "AvatarLogging.h"
@ -668,3 +669,49 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV
DependencyManager::get<NodeList>()->broadcastToNodes(std::move(packet), NodeSet() << NodeType::AvatarMixer);
}
}
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
QJsonArray palData;
auto avatarMap = getHashCopy();
AvatarHash::iterator itr = avatarMap.begin();
while (itr != avatarMap.end()) {
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(*itr);
QString currentSessionUUID = avatar->getSessionUUID().toString();
if (specificAvatarIdentifiers.isEmpty() || specificAvatarIdentifiers.contains(currentSessionUUID)) {
QJsonObject thisAvatarPalData;
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
if (currentSessionUUID == myAvatar->getSessionUUID().toString()) {
currentSessionUUID = "";
}
thisAvatarPalData.insert("sessionUUID", currentSessionUUID);
thisAvatarPalData.insert("sessionDisplayName", avatar->getSessionDisplayName());
thisAvatarPalData.insert("audioLoudness", avatar->getAudioLoudness());
thisAvatarPalData.insert("isReplicated", avatar->getIsReplicated());
glm::vec3 position = avatar->getWorldPosition();
QJsonObject jsonPosition;
jsonPosition.insert("x", position.x);
jsonPosition.insert("y", position.y);
jsonPosition.insert("z", position.z);
thisAvatarPalData.insert("position", jsonPosition);
float palOrbOffset = 0.2f;
int headIndex = avatar->getJointIndex("Head");
if (headIndex > 0) {
glm::vec3 jointTranslation = avatar->getAbsoluteJointTranslationInObjectFrame(headIndex);
palOrbOffset = jointTranslation.y / 2;
}
thisAvatarPalData.insert("palOrbOffset", palOrbOffset);
palData.append(thisAvatarPalData);
}
++itr;
}
QJsonObject doc;
doc.insert("data", palData);
return doc.toVariantMap();
}

View file

@ -157,6 +157,17 @@ public:
*/
Q_INVOKABLE void setAvatarSortCoefficient(const QString& name, const QScriptValue& value);
/**jsdoc
* Used in the PAL for getting PAL-related data about avatars nearby. Using this method is faster
* than iterating over each avatar and obtaining data about them in JavaScript, as that method
* locks and unlocks each avatar's data structure potentially hundreds of times per update tick.
* @function AvatarManager.getPalData
* @param {string[]} specificAvatarIdentifiers - A list of specific Avatar Identifiers about
* which you want to get PAL data
* @returns {object}
*/
Q_INVOKABLE QVariantMap getPalData(const QList<QString> specificAvatarIdentifiers = QList<QString>());
float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); }
int getIdentityRequestsSent() const { return _identityRequestsSent; }

View file

@ -3551,6 +3551,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) {
if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
activate(Rotation);
myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing);
}
if (myAvatar.getCenterOfGravityModelEnabled()) {
if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) {
@ -3568,6 +3569,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
} else {
if (!isActive(Rotation) && getForceActivateRotation()) {
activate(Rotation);
myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing);
setForceActivateRotation(false);
}
if (!isActive(Horizontal) && getForceActivateHorizontal()) {

View file

@ -883,6 +883,7 @@ public:
virtual void rebuildCollisionShape() override;
const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; }
void setHeadControllerFacingMovingAverage(glm::vec2 currentHeadControllerFacing) { _headControllerFacingMovingAverage = currentHeadControllerFacing; }
float getCurrentStandingHeight() const { return _currentStandingHeight; }
void setCurrentStandingHeight(float newMode) { _currentStandingHeight = newMode; }
const glm::quat getAverageHeadRotation() const { return _averageHeadRotation; }

View file

@ -381,7 +381,7 @@ public slots:
/**jsdoc
* Get the rotation of the left palm in world coordinates.
* @function MyAvatar.getLeftPalmRotation
* @returns {Vec3} The rotation of the left palm in world coordinates.
* @returns {Quat} The rotation of the left palm in world coordinates.
* @example <caption>Report the rotation of your avatar's left palm.</caption>
* print(JSON.stringify(MyAvatar.getLeftPalmRotation()));
*/
@ -398,7 +398,7 @@ public slots:
/**jsdoc
* Get the rotation of the right palm in world coordinates.
* @function MyAvatar.getRightPalmRotation
* @returns {Vec3} The rotation of the right palm in world coordinates.
* @returns {Quat} The rotation of the right palm in world coordinates.
* @example <caption>Report the rotation of your avatar's right palm.</caption>
* print(JSON.stringify(MyAvatar.getRightPalmRotation()));
*/

View file

@ -363,12 +363,18 @@ bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity
return false;
}
void EntityRenderer::updateModelTransform() {
void EntityRenderer::updateModelTransformAndBound() {
bool success = false;
auto newModelTransform = _entity->getTransformToCenter(success);
if (success) {
_modelTransform = newModelTransform;
}
success = false;
auto bound = _entity->getAABox(success);
if (success) {
_bound = bound;
}
}
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) {
@ -380,15 +386,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
}
_prevIsTransparent = transparent;
bool success = false;
auto bound = entity->getAABox(success);
if (success) {
_bound = bound;
}
auto newModelTransform = entity->getTransformToCenter(success);
if (success) {
_modelTransform = newModelTransform;
}
updateModelTransformAndBound();
_moving = entity->isMovingRelativeToParent();
_visible = entity->getVisible();

View file

@ -97,7 +97,7 @@ protected:
virtual void doRender(RenderArgs* args) = 0;
bool isFading() const { return _isFading; }
void updateModelTransform();
void updateModelTransformAndBound();
virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; }
inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; }

View file

@ -126,7 +126,7 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] () {
withWriteLock([&] {
updateModelTransform();
updateModelTransformAndBound();
_renderTransform = getModelTransform();
});
});

View file

@ -106,10 +106,8 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
_position = entity->getWorldPosition();
_dimensions = entity->getScaledDimensions();
_orientation = entity->getWorldOrientation();
bool success = false;
auto newModelTransform = entity->getTransformToCenter(success);
_renderTransform = success ? newModelTransform : getModelTransform();
updateModelTransformAndBound();
_renderTransform = getModelTransform();
if (_shape == entity::Sphere) {
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
}

View file

@ -70,7 +70,7 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () {
withWriteLock([&] {
_dimensions = entity->getScaledDimensions();
updateModelTransform();
updateModelTransformAndBound();
_renderTransform = getModelTransform();
});
});

View file

@ -206,7 +206,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
glm::vec2 windowSize = getWindowSize(entity);
_webSurface->resize(QSize(windowSize.x, windowSize.y));
updateModelTransform();
updateModelTransformAndBound();
_renderTransform = getModelTransform();
_renderTransform.postScale(entity->getScaledDimensions());
});

View file

@ -262,24 +262,53 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
btVector3 linearDisplacement = clampLength(vel * dt, MAX_DISPLACEMENT); // clamp displacement to prevent tunneling.
btVector3 endPos = startPos + linearDisplacement;
// resolve the simple linearDisplacement
_followLinearDisplacement += linearDisplacement;
// now for the rotational part...
btQuaternion startRot = bodyTransform.getRotation();
btQuaternion desiredRot = _followDesiredBodyTransform.getRotation();
if (desiredRot.dot(startRot) < 0.0f) {
desiredRot = -desiredRot;
// startRot as default rotation
btQuaternion endRot = startRot;
// the dot product between two quaternions is equal to +/- cos(angle/2)
// where 'angle' is that of the rotation between them
float qDot = desiredRot.dot(startRot);
// when the abs() value of the dot product is approximately 1.0
// then the two rotations are effectively adjacent
const float MIN_DOT_PRODUCT_OF_ADJACENT_QUATERNIONS = 0.99999f; // corresponds to approx 0.5 degrees
if (fabsf(qDot) < MIN_DOT_PRODUCT_OF_ADJACENT_QUATERNIONS) {
if (qDot < 0.0f) {
// the quaternions are actually on opposite hyperhemispheres
// so we move one to agree with the other and negate qDot
desiredRot = -desiredRot;
qDot = -qDot;
}
btQuaternion deltaRot = desiredRot * startRot.inverse();
// the axis is the imaginary part, but scaled by sin(angle/2)
btVector3 axis(deltaRot.getX(), deltaRot.getY(), deltaRot.getZ());
axis /= sqrtf(1.0f - qDot * qDot);
// compute the angle we will resolve for this dt, but don't overshoot
float angle = 2.0f * acosf(qDot);
if ( dt < _followTimeRemaining) {
angle *= dt / _followTimeRemaining;
}
// accumulate rotation
deltaRot = btQuaternion(axis, angle);
_followAngularDisplacement = (deltaRot * _followAngularDisplacement).normalize();
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);
endRot = deltaRot * startRot;
btVector3 swingDisplacement = rotateVector(endRot, -shapeLocalOffset) - rotateVector(startRot, -shapeLocalOffset);
_followLinearDisplacement += swingDisplacement;
}
btQuaternion deltaRot = desiredRot * startRot.inverse();
float angularSpeed = deltaRot.getAngle() / _followTimeRemaining;
glm::vec3 rotationAxis = glm::normalize(glm::axis(bulletToGLM(deltaRot))); // deltaRot.getAxis() is inaccurate
btQuaternion angularDisplacement = btQuaternion(glmToBullet(rotationAxis), angularSpeed * dt);
btQuaternion endRot = angularDisplacement * startRot;
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);
btVector3 swingDisplacement = rotateVector(endRot, -shapeLocalOffset) - rotateVector(startRot, -shapeLocalOffset);
_followLinearDisplacement = linearDisplacement + swingDisplacement + _followLinearDisplacement;
_followAngularDisplacement = angularDisplacement * _followAngularDisplacement;
_rigidBody->setWorldTransform(btTransform(endRot, endPos));
}
_followTime += dt;

View file

@ -159,6 +159,9 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
for(var bookmarkName in message.data.bookmarks) {
var bookmark = message.data.bookmarks[bookmarkName];
if (!bookmark.avatarEntites) { // ensure avatarEntites always exist
bookmark.avatarEntites = [];
}
bookmark.avatarEntites.forEach(function(avatarEntity) {
avatarEntity.properties.localRotationAngles = Quat.safeEulerAngles(avatarEntity.properties.localRotation)

View file

@ -11,7 +11,8 @@
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME,
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity,
distanceBetweenEntityLocalPositionAndBoundingBox
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -172,12 +173,9 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * TEAR_AWAY_CHECK_TIME) {
this.lastUnequipCheckTime = now;
if (props.parentID === MyAvatar.SELF_ID) {
var sensorScaleFactor = MyAvatar.sensorToWorldScale;
var handPosition = controllerData.controllerLocations[this.hand].position;
var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props);
var distance = Vec3.distance(props.position, handPosition);
if ((dist > TEAR_AWAY_DISTANCE) ||
(distance > NEAR_GRAB_RADIUS * sensorScaleFactor)) {
var tearAwayDistance = TEAR_AWAY_DISTANCE * MyAvatar.sensorToWorldScale;
var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props);
if (distance > tearAwayDistance) {
this.autoUnequipCounter++;
} else {
this.autoUnequipCounter = 0;

View file

@ -1573,15 +1573,11 @@ function deleteSelectedEntities() {
Entities.deleteEntity(entityID);
}
}
if (savedProperties.length > 0) {
SelectionManager.clearSelections();
pushCommandForSelections([], savedProperties);
entityListTool.webView.emitScriptEvent(JSON.stringify({
type: "deleted",
ids: deletedIDs
}));
entityListTool.deleteEntities(deletedIDs);
}
}
}
@ -1853,13 +1849,7 @@ var keyReleaseEvent = function (event) {
}
} else if (event.text === 'g') {
if (isActive && selectionManager.hasSelection()) {
var newPosition = selectionManager.worldPosition;
newPosition = Vec3.subtract(newPosition, {
x: 0,
y: selectionManager.worldDimensions.y * 0.5,
z: 0
});
grid.setPosition(newPosition);
grid.moveToSelection();
}
} else if (event.key === KEY_P && event.isControl && !event.isAutoRepeat ) {
if (event.isShifted) {

View file

@ -59,6 +59,7 @@
highlightTargetEntity:true,
clearHighlightedEntities:true,
unhighlightTargetEntity:true
distanceBetweenEntityLocalPositionAndBoundingBox: true
*/
MSECS_PER_SEC = 1000.0;
@ -130,7 +131,9 @@ DISPATCHER_PROPERTIES = [
"type",
"href",
"cloneable",
"cloneDynamic"
"cloneDynamic",
"localPosition",
"localRotation"
];
// priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step
@ -413,6 +416,25 @@ findHandChildEntities = function(hand) {
});
};
distanceBetweenEntityLocalPositionAndBoundingBox = function(entityProps) {
var localPoint = entityProps.localPosition;
var entityXform = new Xform(entityProps.rotation, entityProps.position);
var minOffset = Vec3.multiplyVbyV(entityProps.registrationPoint, entityProps.dimensions);
var maxOffset = Vec3.multiplyVbyV(Vec3.subtract(ONE_VEC, entityProps.registrationPoint), entityProps.dimensions);
var localMin = Vec3.subtract(entityXform.trans, minOffset);
var localMax = Vec3.sum(entityXform.trans, maxOffset);
var v = {x: localPoint.x, y: localPoint.y, z: localPoint.z};
v.x = Math.max(v.x, localMin.x);
v.x = Math.min(v.x, localMax.x);
v.y = Math.max(v.y, localMin.y);
v.y = Math.min(v.y, localMax.y);
v.z = Math.max(v.z, localMin.z);
v.z = Math.min(v.z, localMax.z);
return Vec3.distance(v, localPoint);
};
distanceBetweenPointAndEntityBoundingBox = function(point, entityProps) {
var entityXform = new Xform(entityProps.rotation, entityProps.position);
var localPoint = entityXform.inv().xformPoint(point);

View file

@ -93,12 +93,18 @@ EntityListTool = function() {
};
that.removeEntities = function (deletedIDs, selectedIDs) {
var data = {
emitJSONScriptEvent({
type: 'removeEntities',
deletedIDs: deletedIDs,
selectedIDs: selectedIDs
};
webView.emitScriptEvent(JSON.stringify(data));
});
};
that.deleteEntities = function (deletedIDs) {
emitJSONScriptEvent({
type: "deleted",
ids: deletedIDs
});
};
function valueIfDefined(value) {

View file

@ -1186,10 +1186,17 @@ SelectionDisplay = (function() {
var localRotationZ = Quat.fromPitchYawRollDegrees(rotationDegrees, 0, 0);
var rotationZ = Quat.multiply(rotation, localRotationZ);
worldRotationZ = rotationZ;
var selectionBoxGeometry = {
position: position,
rotation: rotation,
dimensions: dimensions
};
var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry);
// in HMD we clamp the overlays to the bounding box for now so lasers can hit them
// in HMD if outside the bounding box clamp the overlays to the bounding box for now so lasers can hit them
var maxHandleDimension = 0;
if (HMD.active) {
if (HMD.active && !isCameraInsideBox) {
maxHandleDimension = Math.max(dimensions.x, dimensions.y, dimensions.z);
}
@ -1438,12 +1445,6 @@ SelectionDisplay = (function() {
var inModeRotate = isActiveTool(handleRotatePitchRing) ||
isActiveTool(handleRotateYawRing) ||
isActiveTool(handleRotateRollRing);
var selectionBoxGeometry = {
position: position,
rotation: rotation,
dimensions: dimensions
};
var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry);
selectionBoxGeometry.visible = !inModeRotate && !isCameraInsideBox;
Overlays.editOverlay(selectionBox, selectionBoxGeometry);

View file

@ -154,6 +154,12 @@ Grid = function(opts) {
that.emitUpdate();
}
};
that.moveToSelection = function() {
var newPosition = SelectionManager.worldPosition;
newPosition = Vec3.subtract(newPosition, { x: 0, y: SelectionManager.worldDimensions.y * 0.5, z: 0 });
that.setPosition(newPosition);
};
that.emitUpdate = function() {
if (that.onUpdate) {
@ -280,9 +286,7 @@ GridTool = function(opts) {
}
horizontalGrid.setPosition(position);
} else if (action == "moveToSelection") {
var newPosition = selectionManager.worldPosition;
newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 });
grid.setPosition(newPosition);
horizontalGrid.moveToSelection();
}
}
};

View file

@ -19,7 +19,7 @@
var populateNearbyUserList, color, textures, removeOverlays,
controllerComputePickRay, onTabletButtonClicked, onTabletScreenChanged,
receiveMessage, avatarDisconnected, clearLocalQMLDataAndClosePAL,
createAudioInterval, tablet, CHANNEL, getConnectionData, findableByChanged,
tablet, CHANNEL, getConnectionData, findableByChanged,
avatarAdded, avatarRemoved, avatarSessionChanged; // forward references;
// hardcoding these as it appears we cannot traverse the originalTextures in overlays??? Maybe I've missed
@ -447,21 +447,24 @@ function populateNearbyUserList(selectData, oldAudioData) {
verticalAngleNormal = filter && Quat.getRight(orientation),
horizontalAngleNormal = filter && Quat.getUp(orientation);
avatarsOfInterest = {};
avatars.forEach(function (id) {
var avatar = AvatarList.getAvatar(id);
var name = avatar.sessionDisplayName;
var avatarData = AvatarList.getPalData().data;
avatarData.forEach(function (currentAvatarData) {
var id = currentAvatarData.sessionUUID;
var name = currentAvatarData.sessionDisplayName;
if (!name) {
// Either we got a data packet but no identity yet, or something is really messed up. In any case,
// we won't be able to do anything with this user, so don't include them.
// In normal circumstances, a refresh will bring in the new user, but if we're very heavily loaded,
// we could be losing and gaining people randomly.
print('No avatar identity data for', id);
print('No avatar identity data for', currentAvatarData.sessionUUID);
return;
}
if (id && myPosition && (Vec3.distance(avatar.position, myPosition) > filter.distance)) {
if (id && myPosition && (Vec3.distance(currentAvatarData.position, myPosition) > filter.distance)) {
return;
}
var normal = id && filter && Vec3.normalize(Vec3.subtract(avatar.position, myPosition));
var normal = id && filter && Vec3.normalize(Vec3.subtract(currentAvatarData.position, myPosition));
var horizontal = normal && angleBetweenVectorsInPlane(normal, forward, horizontalAngleNormal);
var vertical = normal && angleBetweenVectorsInPlane(normal, forward, verticalAngleNormal);
if (id && filter && ((Math.abs(horizontal) > horizontalHalfAngle) || (Math.abs(vertical) > verticalHalfAngle))) {
@ -480,11 +483,11 @@ function populateNearbyUserList(selectData, oldAudioData) {
personalMute: !!id && Users.getPersonalMuteStatus(id), // expects proper boolean, not null
ignore: !!id && Users.getIgnoreStatus(id), // ditto
isPresent: true,
isReplicated: avatar.isReplicated
isReplicated: currentAvatarData.isReplicated
};
// Everyone needs to see admin status. Username and fingerprint returns default constructor output if the requesting user isn't an admin.
Users.requestUsernameFromID(id);
if (id) {
if (id !== "") {
addAvatarNode(id); // No overlay for ourselves
avatarsOfInterest[id] = true;
} else {
@ -515,30 +518,63 @@ function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
updateUser(data);
}
function updateAudioLevel(avatarData) {
// the VU meter should work similarly to the one in AvatarInputs: log scale, exponentially averaged
// But of course it gets the data at a different rate, so we tweak the averaging ratio and frequency
// of updating (the latter for efficiency too).
var audioLevel = 0.0;
var avgAudioLevel = 0.0;
var data = avatarData.sessionUUID === "" ? myData : ExtendedOverlay.get(avatarData.sessionUUID);
if (data) {
// we will do exponential moving average by taking some the last loudness and averaging
data.accumulatedLevel = AVERAGING_RATIO * (data.accumulatedLevel || 0) + (1 - AVERAGING_RATIO) * (avatarData.audioLoudness);
// add 1 to insure we don't go log() and hit -infinity. Math.log is
// natural log, so to get log base 2, just divide by ln(2).
audioLevel = scaleAudio(Math.log(data.accumulatedLevel + 1) / LOG2);
// decay avgAudioLevel
avgAudioLevel = Math.max((1 - AUDIO_PEAK_DECAY) * (data.avgAudioLevel || 0), audioLevel);
data.avgAudioLevel = avgAudioLevel;
data.audioLevel = audioLevel;
// now scale for the gain. Also, asked to boost the low end, so one simple way is
// to take sqrt of the value. Lets try that, see how it feels.
avgAudioLevel = Math.min(1.0, Math.sqrt(avgAudioLevel * (sessionGains[avatarData.sessionUUID] || 0.75)));
}
var param = {};
var level = [audioLevel, avgAudioLevel];
var userId = avatarData.sessionUUID;
param[userId] = level;
sendToQml({ method: 'updateAudioLevel', params: param });
}
var pingPong = true;
function updateOverlays() {
var eye = Camera.position;
AvatarList.getAvatarIdentifiers().forEach(function (id) {
if (!id || !avatarsOfInterest[id]) {
var avatarData = AvatarList.getPalData().data;
avatarData.forEach(function (currentAvatarData) {
if (currentAvatarData.sessionUUID === "" || !avatarsOfInterest[currentAvatarData.sessionUUID]) {
return; // don't update ourself, or avatars we're not interested in
}
var avatar = AvatarList.getAvatar(id);
if (!avatar) {
return; // will be deleted below if there had been an overlay.
}
var overlay = ExtendedOverlay.get(id);
updateAudioLevel(currentAvatarData);
var overlay = ExtendedOverlay.get(currentAvatarData.sessionUUID);
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
print('Adding non-PAL avatar node', id);
overlay = addAvatarNode(id);
print('Adding non-PAL avatar node', currentAvatarData.sessionUUID);
overlay = addAvatarNode(currentAvatarData.sessionUUID);
}
var target = avatar.position;
var target = currentAvatarData.position;
var distance = Vec3.distance(target, eye);
var offset = 0.2;
var offset = currentAvatarData.palOrbOffset;
var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position)
var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can
if (headIndex > 0) {
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
}
// move a bit in front, towards the camera
target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset));
@ -548,7 +584,7 @@ function updateOverlays() {
overlay.ping = pingPong;
overlay.editOverlay({
color: color(ExtendedOverlay.isSelected(id), overlay.hovering, overlay.audioLevel),
color: color(ExtendedOverlay.isSelected(currentAvatarData.sessionUUID), overlay.hovering, overlay.audioLevel),
position: target,
dimensions: 0.032 * distance
});
@ -704,6 +740,13 @@ function wireEventBridge(on) {
hasEventBridge = false;
}
}
}
var UPDATE_INTERVAL_MS = 100;
function createUpdateInterval() {
return Script.setInterval(function () {
updateOverlays();
}, UPDATE_INTERVAL_MS);
}
function onTabletScreenChanged(type, url) {
@ -719,10 +762,8 @@ function onTabletScreenChanged(type, url) {
ContextOverlay.enabled = false;
Users.requestsDomainListData = true;
audioTimer = createAudioInterval(AUDIO_LEVEL_UPDATE_INTERVAL_MS);
tablet.tabletShownChanged.connect(tabletVisibilityChanged);
Script.update.connect(updateOverlays);
updateInterval = createUpdateInterval();
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
Users.usernameFromIDReply.connect(usernameFromIDReply);
@ -778,50 +819,6 @@ function scaleAudio(val) {
return audioLevel;
}
function getAudioLevel(id) {
// the VU meter should work similarly to the one in AvatarInputs: log scale, exponentially averaged
// But of course it gets the data at a different rate, so we tweak the averaging ratio and frequency
// of updating (the latter for efficiency too).
var avatar = AvatarList.getAvatar(id);
var audioLevel = 0.0;
var avgAudioLevel = 0.0;
var data = id ? ExtendedOverlay.get(id) : myData;
if (data) {
// we will do exponential moving average by taking some the last loudness and averaging
data.accumulatedLevel = AVERAGING_RATIO * (data.accumulatedLevel || 0) + (1 - AVERAGING_RATIO) * (avatar.audioLoudness);
// add 1 to insure we don't go log() and hit -infinity. Math.log is
// natural log, so to get log base 2, just divide by ln(2).
audioLevel = scaleAudio(Math.log(data.accumulatedLevel + 1) / LOG2);
// decay avgAudioLevel
avgAudioLevel = Math.max((1 - AUDIO_PEAK_DECAY) * (data.avgAudioLevel || 0), audioLevel);
data.avgAudioLevel = avgAudioLevel;
data.audioLevel = audioLevel;
// now scale for the gain. Also, asked to boost the low end, so one simple way is
// to take sqrt of the value. Lets try that, see how it feels.
avgAudioLevel = Math.min(1.0, Math.sqrt(avgAudioLevel * (sessionGains[id] || 0.75)));
}
return [audioLevel, avgAudioLevel];
}
function createAudioInterval(interval) {
// we will update the audioLevels periodically
// TODO: tune for efficiency - expecially with large numbers of avatars
return Script.setInterval(function () {
var param = {};
AvatarList.getAvatarIdentifiers().forEach(function (id) {
var level = getAudioLevel(id),
userId = id || 0; // qml didn't like an object with null/empty string for a key, so...
param[userId] = level;
});
sendToQml({method: 'updateAudioLevel', params: param});
}, interval);
}
function avatarDisconnected(nodeID) {
// remove from the pal list
sendToQml({method: 'avatarDisconnected', params: [nodeID]});
@ -874,11 +871,11 @@ startup();
var isWired = false;
var audioTimer;
var AUDIO_LEVEL_UPDATE_INTERVAL_MS = 100; // 10hz for now (change this and change the AVERAGING_RATIO too)
function off() {
if (isWired) {
Script.update.disconnect(updateOverlays);
if (updateInterval) {
Script.clearInterval(updateInterval);
}
Controller.mousePressEvent.disconnect(handleMouseEvent);
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
tablet.tabletShownChanged.disconnect(tabletVisibilityChanged);
@ -889,10 +886,6 @@ function off() {
Users.requestsDomainListData = false;
isWired = false;
if (audioTimer) {
Script.clearInterval(audioTimer);
}
}
removeOverlays();

View file

@ -31,8 +31,8 @@ BakerCLI::BakerCLI(OvenCLIApplication* parent) : QObject(parent) {
void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) {
// if the URL doesn't have a scheme, assume it is a local file
if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp") {
inputUrl.setScheme("file");
if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp" && inputUrl.scheme() != "file") {
inputUrl = QUrl::fromLocalFile(inputUrl.toString());
}
qDebug() << "Baking file type: " << type;