Merge branch 'master' of github.com:highfidelity/hifi into island

This commit is contained in:
Seth Alves 2015-03-31 17:00:48 -07:00
commit 164e5ff816
22 changed files with 264 additions and 168 deletions

View file

@ -45,7 +45,7 @@ Agent::Agent(const QByteArray& packet) :
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender); DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
DependencyManager::set<ResouceCacheSharedItems>(); DependencyManager::set<ResourceCacheSharedItems>();
DependencyManager::set<SoundCache>(); DependencyManager::set<SoundCache>();
} }

View file

@ -19,7 +19,7 @@ if (WIN32)
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip
URL_MD5 f5e8914fc9064ad32e0d62d19d33d977 URL_MD5 f5e8914fc9064ad32e0d62d19d33d977
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 -DUSE_DX11=0
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1
LOG_CONFIGURE 1 LOG_CONFIGURE 1
LOG_BUILD 1 LOG_BUILD 1

View file

@ -13,16 +13,28 @@ if (ANDROID)
BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/AndroidTBBLibCopy.cmake INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=so -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake
LOG_DOWNLOAD 1
LOG_CONFIGURE 1
LOG_BUILD 1
)
elseif (APPLE)
find_program(MAKE_COMMAND NAMES make DOC "Path to the make command")
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz
URL_MD5 bf090eaa86cf89ea014b7b462786a440
BUILD_COMMAND ${MAKE_COMMAND} tbb_os=macos
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=dylib -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake
LOG_DOWNLOAD 1 LOG_DOWNLOAD 1
LOG_CONFIGURE 1 LOG_CONFIGURE 1
LOG_BUILD 1 LOG_BUILD 1
) )
else () else ()
if (APPLE) if (WIN32)
set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_osx.tgz)
set(DOWNLOAD_MD5 25a36ebff070ff801760ec658079f6aa)
elseif (WIN32)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip) set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip)
set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440) set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440)
else () else ()
@ -46,7 +58,7 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (APPLE) if (APPLE)
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/libc++") set(_TBB_LIB_DIR "${SOURCE_DIR}/lib")
set(_LIB_PREFIX "lib") set(_LIB_PREFIX "lib")
set(_LIB_EXT "dylib") set(_LIB_EXT "dylib")
@ -95,14 +107,8 @@ elseif (UNIX)
endif () endif ()
if (DEFINED _TBB_LIB_DIR) if (DEFINED _TBB_LIB_DIR)
if (NOT APPLE) set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location") set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location")
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location")
else ()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "TBB debug library location")
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG "" CACHE FILEPATH "TBB malloc debug library location")
endif ()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location") set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location")
set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location") set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location")
endif () endif ()

View file

@ -10,9 +10,11 @@
# #
# first find the so files in the source dir # first find the so files in the source dir
set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libc++) set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib") file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib")
message(${_TBB_LIBRARIES})
# raise an error if we found none # raise an error if we found none
if (NOT _TBB_LIBRARIES) if (NOT _TBB_LIBRARIES)
message(FATAL_ERROR "Did not find any TBB libraries") message(FATAL_ERROR "Did not find any TBB libraries")
@ -28,20 +30,6 @@ find_program(LIPO_COMMAND NAMES lipo DOC "Path to the lipo command")
foreach(_TBB_LIBRARY ${_TBB_LIBRARIES}) foreach(_TBB_LIBRARY ${_TBB_LIBRARIES})
get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME) get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME)
set(_LIPO_ARGS -remove i386 ${_TBB_LIBRARY_FILENAME} -output ${_TBB_LIBRARY_FILENAME})
message(STATUS "${LIPO_COMMAND} ${_LIPO_ARGS}")
# first we use lipo to remove i386 from each dylib
execute_process(
COMMAND ${LIPO_COMMAND} ${_LIPO_ARGS}
WORKING_DIRECTORY ${_TBB_LIBRARY_DIR}
ERROR_VARIABLE _LIPO_ERROR
)
if (_LIPO_ERROR)
message(FATAL_ERROR "There was an error removing i386 for ${_TBB_LIBRARY_FILENAME} - ${_LIPO_ERROR}")
endif ()
set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME}) set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME})
message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}") message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}")

View file

@ -1,5 +1,5 @@
# #
# AndroidTBBLibCopy.cmake # TBBLibCopy.cmake
# cmake/externals/tbb # cmake/externals/tbb
# #
# Copyright 2015 High Fidelity, Inc. # Copyright 2015 High Fidelity, Inc.
@ -10,7 +10,7 @@
# #
# first find the so files in the source dir # first find the so files in the source dir
file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.so") file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.${TBB_LIBS_SUFFIX}")
# raise an error if we found none # raise an error if we found none
if (NOT _TBB_LIBRARIES) if (NOT _TBB_LIBRARIES)

View file

@ -43,8 +43,8 @@ var floor = Entities.addEntity(
var edge1 = Entities.addEntity( var edge1 = Entities.addEntity(
{ type: "Box", { type: "Box",
position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS },
color: { red: 128, green: 128, blue: 128 }, color: { red: 100, green: 100, blue: 100 },
gravity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: 0, z: 0 },
ignoreCollisions: false, ignoreCollisions: false,
visible: true, visible: true,
@ -54,8 +54,8 @@ var edge1 = Entities.addEntity(
var edge2 = Entities.addEntity( var edge2 = Entities.addEntity(
{ type: "Box", { type: "Box",
position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS },
color: { red: 128, green: 128, blue: 128 }, color: { red: 100, green: 100, blue: 100 },
gravity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: 0, z: 0 },
ignoreCollisions: false, ignoreCollisions: false,
visible: true, visible: true,
@ -65,8 +65,8 @@ var edge2 = Entities.addEntity(
var edge3 = Entities.addEntity( var edge3 = Entities.addEntity(
{ type: "Box", { type: "Box",
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }), position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }),
dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS },
color: { red: 128, green: 128, blue: 128 }, color: { red: 100, green: 100, blue: 100 },
gravity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: 0, z: 0 },
ignoreCollisions: false, ignoreCollisions: false,
visible: true, visible: true,
@ -76,8 +76,8 @@ var edge3 = Entities.addEntity(
var edge4 = Entities.addEntity( var edge4 = Entities.addEntity(
{ type: "Box", { type: "Box",
position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }), position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }),
dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS },
color: { red: 128, green: 128, blue: 128 }, color: { red: 100, green: 100, blue: 100 },
gravity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: 0, z: 0 },
ignoreCollisions: false, ignoreCollisions: false,
visible: true, visible: true,
@ -97,6 +97,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE }, dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE },
color: { red: type.red, green: type.green, blue: type.blue }, color: { red: type.red, green: type.green, blue: type.blue },
gravity: { x: 0, y: GRAVITY, z: 0 }, gravity: { x: 0, y: GRAVITY, z: 0 },
velocity: { x: 0, y: 0.05, z: 0 },
ignoreCollisions: false, ignoreCollisions: false,
damping: DAMPING, damping: DAMPING,
lifetime: LIFETIME, lifetime: LIFETIME,
@ -104,6 +105,11 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
} }
function scriptEnding() { function scriptEnding() {
Entities.editEntity(edge1, { locked: false });
Entities.editEntity(edge2, { locked: false });
Entities.editEntity(edge3, { locked: false });
Entities.editEntity(edge4, { locked: false });
Entities.editEntity(floor, { locked: false });
Entities.deleteEntity(edge1); Entities.deleteEntity(edge1);
Entities.deleteEntity(edge2); Entities.deleteEntity(edge2);
Entities.deleteEntity(edge3); Entities.deleteEntity(edge3);

View file

@ -210,6 +210,9 @@
disableChildren(document.getElementById("properties-list"), 'input'); disableChildren(document.getElementById("properties-list"), 'input');
} else { } else {
var activeElement = document.activeElement;
var selected = activeElement.selectionStart == 0 && activeElement.selectionEnd == activeElement.value.length;
var properties = data.selections[0].properties; var properties = data.selections[0].properties;
elID.innerHTML = properties.id; elID.innerHTML = properties.id;
@ -335,6 +338,11 @@
elLightExponent.value = properties.exponent; elLightExponent.value = properties.exponent;
elLightCutoff.value = properties.cutoff; elLightCutoff.value = properties.cutoff;
} }
if (selected) {
activeElement.focus();
activeElement.select();
}
} }
} }
}); });

View file

@ -11,8 +11,11 @@
var usersWindow = (function () { var usersWindow = (function () {
var WINDOW_WIDTH_2D = 160, var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/",
WINDOW_WIDTH_2D = 160,
WINDOW_MARGIN_2D = 12, WINDOW_MARGIN_2D = 12,
WINDOW_BASE_MARGIN_2D = 6, // A little less is needed in order look correct
WINDOW_FONT_2D = { size: 12 }, WINDOW_FONT_2D = { size: 12 },
WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 }, WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 },
WINDOW_FOREGROUND_ALPHA_2D = 0.9, WINDOW_FOREGROUND_ALPHA_2D = 0.9,
@ -22,6 +25,14 @@ var usersWindow = (function () {
WINDOW_BACKGROUND_ALPHA_2D = 0.7, WINDOW_BACKGROUND_ALPHA_2D = 0.7,
windowPane2D, windowPane2D,
windowHeading2D, windowHeading2D,
MINIMIZE_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/tools/min-max-toggle.svg",
MINIMIZE_BUTTON_SVG_WIDTH = 17.1,
MINIMIZE_BUTTON_SVG_HEIGHT = 32.5,
MINIMIZE_BUTTON_WIDTH_2D = 14,
MINIMIZE_BUTTON_HEIGHT_2D = MINIMIZE_BUTTON_WIDTH_2D,
MINIMIZE_BUTTON_COLOR_2D = { red: 255, green: 255, blue: 255 },
MINIMIZE_BUTTON_ALPHA_2D = 0.9,
minimizeButton2D,
SCROLLBAR_BACKGROUND_WIDTH_2D = 12, SCROLLBAR_BACKGROUND_WIDTH_2D = 12,
SCROLLBAR_BACKGROUND_COLOR_2D = { red: 80, green: 80, blue: 80 }, SCROLLBAR_BACKGROUND_COLOR_2D = { red: 80, green: 80, blue: 80 },
SCROLLBAR_BACKGROUND_ALPHA_2D = 0.8, SCROLLBAR_BACKGROUND_ALPHA_2D = 0.8,
@ -65,6 +76,7 @@ var usersWindow = (function () {
MENU_ITEM_AFTER = "Chat...", MENU_ITEM_AFTER = "Chat...",
isVisible = true, isVisible = true,
isMinimized = false,
viewportHeight, viewportHeight,
isMirrorDisplay = false, isMirrorDisplay = false,
@ -77,7 +89,6 @@ var usersWindow = (function () {
scrollbarBarClickedAt, // 0.0 .. 1.0 scrollbarBarClickedAt, // 0.0 .. 1.0
scrollbarValue = 0.0, // 0.0 .. 1.0 scrollbarValue = 0.0, // 0.0 .. 1.0
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/",
RADIO_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/radio-button.svg", RADIO_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/radio-button.svg",
RADIO_BUTTON_SVG_DIAMETER = 14, RADIO_BUTTON_SVG_DIAMETER = 14,
RADIO_BUTTON_DISPLAY_SCALE = 0.7, // 1.0 = windowTextHeight RADIO_BUTTON_DISPLAY_SCALE = 0.7, // 1.0 = windowTextHeight
@ -89,9 +100,15 @@ var usersWindow = (function () {
nonUsersHeight, nonUsersHeight,
maxWindowHeight; maxWindowHeight;
if (isMinimized) {
windowHeight = windowTextHeight + WINDOW_MARGIN_2D + WINDOW_BASE_MARGIN_2D;
return;
}
// Reserve 5 lines for window heading plus visibility heading and controls // Reserve 5 lines for window heading plus visibility heading and controls
// Subtract windowLineSpacing for both end of user list and end of controls // Subtract windowLineSpacing for both end of user list and end of controls
nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + 2 * WINDOW_MARGIN_2D; nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + WINDOW_MARGIN_2D
+ WINDOW_BASE_MARGIN_2D;
// Limit window to height of viewport minus VU meter and mirror if displayed // Limit window to height of viewport minus VU meter and mirror if displayed
windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight; windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight;
@ -102,7 +119,7 @@ var usersWindow = (function () {
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight); windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
// Corresponding number of users to actually display // Corresponding number of users to actually display
numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0); numUsersToDisplay = Math.max(Math.floor((windowHeight - nonUsersHeight) / windowLineHeight), 0);
isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length; isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length;
if (isUsingScrollbars) { if (isUsingScrollbars) {
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
@ -123,6 +140,10 @@ var usersWindow = (function () {
y: viewportHeight - windowHeight + WINDOW_MARGIN_2D y: viewportHeight - windowHeight + WINDOW_MARGIN_2D
}); });
Overlays.editOverlay(minimizeButton2D, {
y: viewportHeight - windowHeight + WINDOW_MARGIN_2D / 2
});
scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN_2D + windowTextHeight; scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN_2D + windowTextHeight;
Overlays.editOverlay(scrollbarBackground2D, { Overlays.editOverlay(scrollbarBackground2D, {
y: scrollbarBackgroundPosition.y y: scrollbarBackgroundPosition.y
@ -133,10 +154,10 @@ var usersWindow = (function () {
y: scrollbarBarPosition.y y: scrollbarBarPosition.y
}); });
Overlays.editOverlay(visibilityHeading2D, { Overlays.editOverlay(visibilityHeading2D, {
y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D
}); });
for (i = 0; i < visibilityControls2D.length; i += 1) { for (i = 0; i < visibilityControls2D.length; i += 1) {
y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D; y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D;
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { y: y }); Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { y: y });
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { y: y }); Overlays.editOverlay(visibilityControls2D[i].textOverlay, { y: y });
} }
@ -166,29 +187,43 @@ var usersWindow = (function () {
reducedTextWidth, reducedTextWidth,
i; i;
maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D; if (!isMinimized) {
ellipsisWidth = Overlays.textSize(windowPane2D, "...").width; maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D;
reducedTextWidth = maxTextWidth - ellipsisWidth; ellipsisWidth = Overlays.textSize(windowPane2D, "...").width;
reducedTextWidth = maxTextWidth - ellipsisWidth;
for (i = 0; i < numUsersToDisplay; i += 1) { for (i = 0; i < numUsersToDisplay; i += 1) {
user = usersOnline[linesOfUsers[firstUserToDisplay + i]]; user = usersOnline[linesOfUsers[firstUserToDisplay + i]];
userText = user.text; userText = user.text;
textWidth = user.textWidth; textWidth = user.textWidth;
if (textWidth > maxTextWidth) { if (textWidth > maxTextWidth) {
// Trim and append "..." to fit window width // Trim and append "..." to fit window width
maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width; maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width;
while (textWidth > reducedTextWidth) { while (textWidth > reducedTextWidth) {
userText = userText.slice(0, -1); userText = userText.slice(0, -1);
textWidth = Overlays.textSize(windowPane2D, userText).width; textWidth = Overlays.textSize(windowPane2D, userText).width;
}
userText += "...";
} }
userText += "...";
displayText += "\n" + userText;
} }
displayText += "\n" + userText; displayText = displayText.slice(1); // Remove leading "\n".
}
displayText = displayText.slice(1); // Remove leading "\n". scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2;
Overlays.editOverlay(scrollbarBackground2D, {
height: scrollbarBackgroundHeight,
visible: isUsingScrollbars
});
scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight,
SCROLLBAR_BAR_MIN_HEIGHT);
Overlays.editOverlay(scrollbarBar2D, {
height: scrollbarBarHeight,
visible: isUsingScrollbars
});
}
Overlays.editOverlay(windowPane2D, { Overlays.editOverlay(windowPane2D, {
height: windowHeight, height: windowHeight,
@ -198,20 +233,6 @@ var usersWindow = (function () {
Overlays.editOverlay(windowHeading2D, { Overlays.editOverlay(windowHeading2D, {
text: linesOfUsers.length > 0 ? "Users online" : "No users online" text: linesOfUsers.length > 0 ? "Users online" : "No users online"
}); });
scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2;
Overlays.editOverlay(scrollbarBackground2D, {
height: scrollbarBackgroundHeight,
visible: isUsingScrollbars
});
scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight,
SCROLLBAR_BAR_MIN_HEIGHT);
Overlays.editOverlay(scrollbarBar2D, {
height: scrollbarBarHeight,
visible: isUsingScrollbars
});
updateOverlayPositions();
} }
function pollUsers() { function pollUsers() {
@ -264,6 +285,7 @@ var usersWindow = (function () {
calculateWindowHeight(); calculateWindowHeight();
updateUsersDisplay(); updateUsersDisplay();
updateOverlayPositions();
} else { } else {
print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText); print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText);
@ -289,9 +311,22 @@ var usersWindow = (function () {
} }
} }
function setVisible(visible) { function updateOverlayVisibility() {
var i; var i;
Overlays.editOverlay(windowPane2D, { visible: isVisible });
Overlays.editOverlay(windowHeading2D, { visible: isVisible });
Overlays.editOverlay(minimizeButton2D, { visible: isVisible });
Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
Overlays.editOverlay(visibilityHeading2D, { visible: isVisible && !isMinimized });
for (i = 0; i < visibilityControls2D.length; i += 1) {
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible && !isMinimized });
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible && !isMinimized });
}
}
function setVisible(visible) {
isVisible = visible; isVisible = visible;
if (isVisible) { if (isVisible) {
@ -303,15 +338,15 @@ var usersWindow = (function () {
usersTimer = null; usersTimer = null;
} }
Overlays.editOverlay(windowPane2D, { visible: isVisible }); updateOverlayVisibility();
Overlays.editOverlay(windowHeading2D, { visible: isVisible }); }
Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars });
Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars }); function setMinimized(minimized) {
Overlays.editOverlay(visibilityHeading2D, { visible: isVisible }); isMinimized = minimized;
for (i = 0; i < visibilityControls2D.length; i += 1) { Overlays.editOverlay(minimizeButton2D, {
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible }); subImage: { y: isMinimized ? MINIMIZE_BUTTON_SVG_HEIGHT / 2 : 0 }
Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible }); });
} updateOverlayVisibility();
} }
function onMenuItemEvent(event) { function onMenuItemEvent(event) {
@ -360,6 +395,8 @@ var usersWindow = (function () {
//print("Go to " + usersOnline[linesOfUsers[userClicked]].username); //print("Go to " + usersOnline[linesOfUsers[userClicked]].username);
location.goToUser(usersOnline[linesOfUsers[userClicked]].username); location.goToUser(usersOnline[linesOfUsers[userClicked]].username);
} }
return;
} }
visibilityChanged = false; visibilityChanged = false;
@ -376,6 +413,15 @@ var usersWindow = (function () {
visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay; visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay;
} }
updateVisibilityControls(); updateVisibilityControls();
return;
}
if (clickedOverlay === minimizeButton2D) {
setMinimized(!isMinimized);
calculateWindowHeight();
updateOverlayPositions();
updateUsersDisplay();
return;
} }
if (clickedOverlay === scrollbarBar2D) { if (clickedOverlay === scrollbarBar2D) {
@ -384,6 +430,7 @@ var usersWindow = (function () {
backgroundAlpha: SCROLLBAR_BAR_SELECTED_ALPHA_2D backgroundAlpha: SCROLLBAR_BAR_SELECTED_ALPHA_2D
}); });
isMovingScrollbar = true; isMovingScrollbar = true;
return;
} }
if (clickedOverlay === scrollbarBackground2D) { if (clickedOverlay === scrollbarBackground2D) {
@ -398,6 +445,7 @@ var usersWindow = (function () {
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
updateOverlayPositions(); updateOverlayPositions();
updateUsersDisplay(); updateUsersDisplay();
return;
} }
} }
@ -492,7 +540,19 @@ var usersWindow = (function () {
backgroundAlpha: 0.0, backgroundAlpha: 0.0,
text: "No users online", text: "No users online",
font: WINDOW_FONT_2D, font: WINDOW_FONT_2D,
visible: isVisible visible: isVisible && !isMinimized
});
minimizeButton2D = Overlays.addOverlay("image", {
x: WINDOW_WIDTH_2D - WINDOW_MARGIN_2D / 2 - MINIMIZE_BUTTON_WIDTH_2D,
y: viewportHeight,
width: MINIMIZE_BUTTON_WIDTH_2D,
height: MINIMIZE_BUTTON_HEIGHT_2D,
imageURL: MINIMIZE_BUTTON_SVG,
subImage: { x: 0, y: 0, width: MINIMIZE_BUTTON_SVG_WIDTH, height: MINIMIZE_BUTTON_SVG_HEIGHT / 2 },
color: MINIMIZE_BUTTON_COLOR_2D,
alpha: MINIMIZE_BUTTON_ALPHA_2D,
visible: isVisible && !isMinimized
}); });
scrollbarBackgroundPosition = { scrollbarBackgroundPosition = {
@ -507,7 +567,7 @@ var usersWindow = (function () {
backgroundColor: SCROLLBAR_BACKGROUND_COLOR_2D, backgroundColor: SCROLLBAR_BACKGROUND_COLOR_2D,
backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA_2D, backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA_2D,
text: "", text: "",
visible: isVisible && isUsingScrollbars visible: isVisible && isUsingScrollbars && !isMinimized
}); });
scrollbarBarPosition = { scrollbarBarPosition = {
@ -522,7 +582,7 @@ var usersWindow = (function () {
backgroundColor: SCROLLBAR_BAR_COLOR_2D, backgroundColor: SCROLLBAR_BAR_COLOR_2D,
backgroundAlpha: SCROLLBAR_BAR_ALPHA_2D, backgroundAlpha: SCROLLBAR_BAR_ALPHA_2D,
text: "", text: "",
visible: isVisible && isUsingScrollbars visible: isVisible && isUsingScrollbars && !isMinimized
}); });
visibilityHeading2D = Overlays.addOverlay("text", { visibilityHeading2D = Overlays.addOverlay("text", {
@ -537,7 +597,7 @@ var usersWindow = (function () {
backgroundAlpha: 0.0, backgroundAlpha: 0.0,
text: "I am visible to:", text: "I am visible to:",
font: WINDOW_FONT_2D, font: WINDOW_FONT_2D,
visible: isVisible visible: isVisible && !isMinimized
}); });
myVisibility = GlobalServices.findableBy; myVisibility = GlobalServices.findableBy;
@ -561,7 +621,8 @@ var usersWindow = (function () {
height: RADIO_BUTTON_SVG_DIAMETER height: RADIO_BUTTON_SVG_DIAMETER
}, },
color: WINDOW_HEADING_COLOR_2D, color: WINDOW_HEADING_COLOR_2D,
alpha: WINDOW_FOREGROUND_ALPHA_2D alpha: WINDOW_FOREGROUND_ALPHA_2D,
visible: isVisible && !isMinimized
}), }),
textOverlay: Overlays.addOverlay("text", { textOverlay: Overlays.addOverlay("text", {
x: WINDOW_MARGIN_2D, x: WINDOW_MARGIN_2D,
@ -575,7 +636,7 @@ var usersWindow = (function () {
backgroundAlpha: 0.0, backgroundAlpha: 0.0,
text: optionText, text: optionText,
font: WINDOW_FONT_2D, font: WINDOW_FONT_2D,
visible: isVisible visible: isVisible && !isMinimized
}), }),
selected: myVisibility === VISIBILITY_VALUES[0] selected: myVisibility === VISIBILITY_VALUES[0]
}]; }];
@ -634,6 +695,7 @@ var usersWindow = (function () {
Script.clearTimeout(usersTimer); Script.clearTimeout(usersTimer);
Overlays.deleteOverlay(windowPane2D); Overlays.deleteOverlay(windowPane2D);
Overlays.deleteOverlay(windowHeading2D); Overlays.deleteOverlay(windowHeading2D);
Overlays.deleteOverlay(minimizeButton2D);
Overlays.deleteOverlay(scrollbarBackground2D); Overlays.deleteOverlay(scrollbarBackground2D);
Overlays.deleteOverlay(scrollbarBar2D); Overlays.deleteOverlay(scrollbarBar2D);
Overlays.deleteOverlay(visibilityHeading2D); Overlays.deleteOverlay(visibilityHeading2D);

View file

@ -136,6 +136,13 @@
#include "ui/StandAloneJSConsole.h" #include "ui/StandAloneJSConsole.h"
#include "ui/Stats.h" #include "ui/Stats.h"
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
#if defined(Q_OS_WIN)
extern "C" {
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
#endif
using namespace std; using namespace std;
// Starfield information // Starfield information
@ -241,7 +248,7 @@ bool setupEssentials(int& argc, char** argv) {
auto jsConsole = DependencyManager::set<StandAloneJSConsole>(); auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
auto dialogsManager = DependencyManager::set<DialogsManager>(); auto dialogsManager = DependencyManager::set<DialogsManager>();
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>(); auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
auto resouceCacheSharedItems = DependencyManager::set<ResouceCacheSharedItems>(); auto resourceCacheSharedItems = DependencyManager::set<ResourceCacheSharedItems>();
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>(); auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
auto windowScriptingInterface = DependencyManager::set<WindowScriptingInterface>(); auto windowScriptingInterface = DependencyManager::set<WindowScriptingInterface>();
#if defined(Q_OS_MAC) || defined(Q_OS_WIN) #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
@ -646,6 +653,11 @@ void Application::initializeGL() {
} }
#endif #endif
qDebug() << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
qDebug() << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
qDebug() << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR));
qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER));
#ifdef WIN32 #ifdef WIN32
GLenum err = glewInit(); GLenum err = glewInit();
if (GLEW_OK != err) { if (GLEW_OK != err) {

View file

@ -101,7 +101,7 @@ void EntityTreeRenderer::init() {
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity); connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload); connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity);
connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging); connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging);
connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID); connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID);
} }
@ -193,7 +193,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre
// can accomplish all we need to here with just the script "text" and the ID. // can accomplish all we need to here with just the script "text" and the ID.
EntityItemID entityID = entity->getEntityItemID(); EntityItemID entityID = entity->getEntityItemID();
QString entityScript = entity->getScript(); QString entityScript = entity->getScript();
if (_entityScripts.contains(entityID)) { if (_entityScripts.contains(entityID)) {
EntityScriptDetails details = _entityScripts[entityID]; EntityScriptDetails details = _entityScripts[entityID];
@ -217,7 +217,6 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre
if (isPending && isPreload && isURL) { if (isPending && isPreload && isURL) {
_waitingOnPreload.insert(url, entityID); _waitingOnPreload.insert(url, entityID);
} }
auto scriptCache = DependencyManager::get<ScriptCache>(); auto scriptCache = DependencyManager::get<ScriptCache>();
@ -941,6 +940,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
_entityScripts.remove(entityID); _entityScripts.remove(entityID);
} }
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
checkAndCallPreload(entityID);
}
void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) { void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) {
if (_tree && !_shuttingDown) { if (_tree && !_shuttingDown) {
checkAndCallUnload(entityID); checkAndCallUnload(entityID);

View file

@ -105,6 +105,7 @@ signals:
void leaveEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID);
public slots: public slots:
void addingEntity(const EntityItemID& entityID);
void deletingEntity(const EntityItemID& entityID); void deletingEntity(const EntityItemID& entityID);
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
void entitySciptChanging(const EntityItemID& entityID); void entitySciptChanging(const EntityItemID& entityID);

View file

@ -404,7 +404,8 @@ void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
EntityItem* foundEntity = NULL; EntityItem* foundEntity = NULL;
EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion(); EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion();
EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion(); EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion();
_changedEntityIDs[creatorTokenVersion] = knownIDVersion;
// First look for and find the "viewed version" of this entity... it's possible we got // First look for and find the "viewed version" of this entity... it's possible we got
// the known ID version sent to us between us creating our local version, and getting this // the known ID version sent to us between us creating our local version, and getting this
@ -592,6 +593,9 @@ EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /
EntityTreeElement* containingElement = getContainingElement(entityID); EntityTreeElement* containingElement = getContainingElement(entityID);
if (containingElement) { if (containingElement) {
foundEntity = containingElement->getEntityWithEntityItemID(entityID); foundEntity = containingElement->getEntityWithEntityItemID(entityID);
if (!foundEntity && _changedEntityIDs.contains(entityID)) {
foundEntity = containingElement->getEntityWithEntityItemID(_changedEntityIDs[entityID]);
}
} }
return foundEntity; return foundEntity;
} }
@ -958,6 +962,12 @@ EntityTreeElement* EntityTree::getContainingElement(const EntityItemID& entityIt
creatorTokenOnly.isKnownID = false; creatorTokenOnly.isKnownID = false;
element = _entityToElementMap.value(creatorTokenOnly); element = _entityToElementMap.value(creatorTokenOnly);
} }
// If we still didn't find the entity, but the ID was in our changed entityIDs, search for the new ID version
if (!element && _changedEntityIDs.contains(entityItemID)) {
element = getContainingElement(_changedEntityIDs[entityItemID]);
}
return element; return element;
} }

View file

@ -195,6 +195,7 @@ private:
EntityItemFBXService* _fbxService; EntityItemFBXService* _fbxService;
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap; QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
QHash<EntityItemID, EntityItemID> _changedEntityIDs;
EntitySimulation* _simulation; EntitySimulation* _simulation;

View file

@ -133,7 +133,7 @@ void ResourceCache::reserveUnusedResource(qint64 resourceSize) {
} }
void ResourceCache::attemptRequest(Resource* resource) { void ResourceCache::attemptRequest(Resource* resource) {
auto sharedItems = DependencyManager::get<ResouceCacheSharedItems>(); auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
if (_requestLimit <= 0) { if (_requestLimit <= 0) {
// wait until a slot becomes available // wait until a slot becomes available
sharedItems->_pendingRequests.append(resource); sharedItems->_pendingRequests.append(resource);
@ -146,7 +146,7 @@ void ResourceCache::attemptRequest(Resource* resource) {
void ResourceCache::requestCompleted(Resource* resource) { void ResourceCache::requestCompleted(Resource* resource) {
auto sharedItems = DependencyManager::get<ResouceCacheSharedItems>(); auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
sharedItems->_loadingRequests.removeOne(resource); sharedItems->_loadingRequests.removeOne(resource);
_requestLimit++; _requestLimit++;

View file

@ -48,14 +48,14 @@ static const qint64 MAX_UNUSED_MAX_SIZE = 10 * BYTES_PER_GIGABYTES;
// ResourceCache derived classes. Since we can't count on the ordering of // ResourceCache derived classes. Since we can't count on the ordering of
// static members destruction, we need to use this Dependency manager implemented // static members destruction, we need to use this Dependency manager implemented
// object instead // object instead
class ResouceCacheSharedItems : public Dependency { class ResourceCacheSharedItems : public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
public: public:
QList<QPointer<Resource> > _pendingRequests; QList<QPointer<Resource> > _pendingRequests;
QList<Resource*> _loadingRequests; QList<Resource*> _loadingRequests;
private: private:
ResouceCacheSharedItems() { } ResourceCacheSharedItems() { }
virtual ~ResouceCacheSharedItems() { } virtual ~ResourceCacheSharedItems() { }
}; };
@ -71,10 +71,10 @@ public:
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; } qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
static const QList<Resource*>& getLoadingRequests() static const QList<Resource*>& getLoadingRequests()
{ return DependencyManager::get<ResouceCacheSharedItems>()->_loadingRequests; } { return DependencyManager::get<ResourceCacheSharedItems>()->_loadingRequests; }
static int getPendingRequestCount() static int getPendingRequestCount()
{ return DependencyManager::get<ResouceCacheSharedItems>()->_pendingRequests.size(); } { return DependencyManager::get<ResourceCacheSharedItems>()->_pendingRequests.size(); }
ResourceCache(QObject* parent = NULL); ResourceCache(QObject* parent = NULL);
virtual ~ResourceCache(); virtual ~ResourceCache();

48
libraries/physics/src/CharacterController.cpp Normal file → Executable file
View file

@ -274,7 +274,6 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
_currentPosition = _ghostObject->getWorldTransform().getOrigin(); _currentPosition = _ghostObject->getWorldTransform().getOrigin();
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
btVector3 currentPosition = _currentPosition; btVector3 currentPosition = _currentPosition;
@ -308,7 +307,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
btVector3 normal = pt.m_normalWorldOnB; btVector3 normal = pt.m_normalWorldOnB;
normal *= directionSign; // always points from object to character normal *= directionSign; // always points from object to character
btScalar normalDotUp = normal.dot(up); btScalar normalDotUp = normal.dot(_currentUp);
if (normalDotUp < _maxSlopeCosine) { if (normalDotUp < _maxSlopeCosine) {
// this contact has a non-vertical normal... might need to ignored // this contact has a non-vertical normal... might need to ignored
btVector3 collisionPoint; btVector3 collisionPoint;
@ -319,9 +318,9 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
} }
// we do math in frame where character base is origin // we do math in frame where character base is origin
btVector3 characterBase = currentPosition - (_radius + _halfHeight) * up; btVector3 characterBase = currentPosition - (_radius + _halfHeight) * _currentUp;
collisionPoint -= characterBase; collisionPoint -= characterBase;
btScalar collisionHeight = collisionPoint.dot(up); btScalar collisionHeight = collisionPoint.dot(_currentUp);
if (collisionHeight < _lastStepUp) { if (collisionHeight < _lastStepUp) {
// This contact is below the lastStepUp, so we ignore it for penetration resolution, // This contact is below the lastStepUp, so we ignore it for penetration resolution,
@ -357,11 +356,10 @@ void CharacterController::scanDown(btCollisionWorld* world) {
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS);
btVector3 start = _currentPosition; btVector3 start = _currentPosition;
const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight + _radius; // closest possible floor for disabling hover const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight + _radius; // closest possible floor for disabling hover
const btScalar MIN_HOVER_HEIGHT = 3.0f + _halfHeight + _radius; // distance to floor for enabling hover const btScalar MIN_HOVER_HEIGHT = 3.0f + _halfHeight + _radius; // distance to floor for enabling hover
btVector3 end = start - MAX_SCAN_HEIGHT * up; btVector3 end = start - MAX_SCAN_HEIGHT * _currentUp;
world->rayTest(start, end, callback); world->rayTest(start, end, callback);
if (!callback.hasHit()) { if (!callback.hasHit()) {
@ -377,15 +375,14 @@ void CharacterController::stepUp(btCollisionWorld* world) {
// compute start and end // compute start and end
btTransform start, end; btTransform start, end;
start.setIdentity(); start.setIdentity();
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); start.setOrigin(_currentPosition + _currentUp * (_convexShape->getMargin() + _addedMargin));
start.setOrigin(_currentPosition + up * (_convexShape->getMargin() + _addedMargin));
_targetPosition = _currentPosition + up * _stepUpHeight; _targetPosition = _currentPosition + _currentUp * _stepUpHeight;
end.setIdentity(); end.setIdentity();
end.setOrigin(_targetPosition); end.setOrigin(_targetPosition);
// sweep up // sweep up
btVector3 sweepDirNegative = - up; btVector3 sweepDirNegative = - _currentUp;
btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071)); btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071));
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
@ -397,7 +394,7 @@ void CharacterController::stepUp(btCollisionWorld* world) {
_verticalOffset = 0.0f; _verticalOffset = 0.0f;
// Only modify the position if the hit was a slope and not a wall or ceiling. // Only modify the position if the hit was a slope and not a wall or ceiling.
if (callback.m_hitNormalWorld.dot(up) > 0.0f) { if (callback.m_hitNormalWorld.dot(_currentUp) > 0.0f) {
_lastStepUp = _stepUpHeight * callback.m_closestHitFraction; _lastStepUp = _stepUpHeight * callback.m_closestHitFraction;
_currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction); _currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction);
} else { } else {
@ -469,8 +466,8 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt
// sweep forward // sweep forward
btVector3 sweepDirNegative(_currentPosition - _targetPosition); btVector3 sweepDirNegative(_currentPosition - _targetPosition);
btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.0)); btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.0));
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
_ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); _ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
if (callback.hasHit()) { if (callback.hasHit()) {
@ -502,17 +499,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt
// reach of the character's feet. // reach of the character's feet.
// first sweep for ledge // first sweep for ledge
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 step = (_verticalVelocity * dt - _lastStepUp) * _currentUp;
btVector3 step = (_verticalVelocity * dt - _lastStepUp) * up;
StepDownConvexResultCallback callback(_ghostObject, StepDownConvexResultCallback callback(_ghostObject,
up, _currentUp,
_currentPosition, step, _currentPosition, step,
_walkDirection, _walkDirection,
_maxSlopeCosine, _maxSlopeCosine,
_radius, _halfHeight); _radius, _halfHeight);
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
btTransform start, end; btTransform start, end;
start.setIdentity(); start.setIdentity();
@ -532,16 +528,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt
_isOnGround = true; _isOnGround = true;
} else if (!_isJumping) { } else if (!_isJumping) {
// sweep again for floor within downStep threshold // sweep again for floor within downStep threshold
step = -_stepDownHeight * up; step = -_stepDownHeight * _currentUp;
StepDownConvexResultCallback callback2 (_ghostObject, StepDownConvexResultCallback callback2 (_ghostObject,
up, _currentUp,
_currentPosition, step, _currentPosition, step,
_walkDirection, _walkDirection,
_maxSlopeCosine, _maxSlopeCosine,
_radius, _halfHeight); _radius, _halfHeight);
callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback2.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; callback2.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask;
_currentPosition = _targetPosition; _currentPosition = _targetPosition;
_targetPosition = _currentPosition + step; _targetPosition = _currentPosition + step;
@ -617,10 +613,10 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) {
} }
} }
// the CharacterController algorithm can only change the position,
// so we don't bother to pull the rotation out of the transform
const btTransform& transform = _ghostObject->getWorldTransform(); const btTransform& transform = _ghostObject->getWorldTransform();
_currentRotation = transform.getRotation();
_currentPosition = transform.getOrigin(); _currentPosition = transform.getOrigin();
_targetPosition = _currentPosition;
} }
void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) { void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) {
@ -868,6 +864,7 @@ void CharacterController::updateShapeIfNecessary() {
void CharacterController::preSimulation(btScalar timeStep) { void CharacterController::preSimulation(btScalar timeStep) {
if (_enabled && _dynamicsWorld) { if (_enabled && _dynamicsWorld) {
glm::quat rotation = _avatarData->getOrientation(); glm::quat rotation = _avatarData->getOrientation();
_currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset;
btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity());
@ -895,8 +892,7 @@ void CharacterController::postSimulation() {
// cap the velocity of the step so that the character doesn't POP! so hard on steps // cap the velocity of the step so that the character doesn't POP! so hard on steps
glm::vec3 finalStep = position - _lastPosition; glm::vec3 finalStep = position - _lastPosition;
btVector3 finalVelocity = _walkDirection; btVector3 finalVelocity = _walkDirection;
btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); finalVelocity += _verticalVelocity * _currentUp;
finalVelocity += _verticalVelocity * up;
const btScalar MAX_RESOLUTION_SPEED = 5.0f; // m/sec const btScalar MAX_RESOLUTION_SPEED = 5.0f; // m/sec
btScalar maxStepLength = glm::max(MAX_RESOLUTION_SPEED, 2.0f * finalVelocity.length()) * _stepDt; btScalar maxStepLength = glm::max(MAX_RESOLUTION_SPEED, 2.0f * finalVelocity.length()) * _stepDt;
btScalar stepLength = glm::length(finalStep); btScalar stepLength = glm::length(finalStep);

View file

@ -42,9 +42,22 @@ class btPairCachingGhostObject;
ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInterface ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInterface
{ {
protected: protected:
///this is the desired walk direction, set by the user
btVector3 _walkDirection;
btVector3 _normalizedDirection;
//some internal variables
btVector3 _currentPosition;
btVector3 _currentUp;
btVector3 _targetPosition;
glm::vec3 _lastPosition;
btVector3 _floorNormal; // points from object to character
glm::vec3 _shapeLocalOffset;
glm::vec3 _boxScale; // used to compute capsule shape
AvatarData* _avatarData = NULL; AvatarData* _avatarData = NULL;
btPairCachingGhostObject* _ghostObject; btPairCachingGhostObject* _ghostObject = NULL;
btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast
btScalar _radius; btScalar _radius;
@ -64,22 +77,12 @@ protected:
btScalar _addedMargin;//@todo: remove this and fix the code btScalar _addedMargin;//@todo: remove this and fix the code
///this is the desired walk direction, set by the user
btVector3 _walkDirection;
btVector3 _normalizedDirection;
//some internal variables
btVector3 _currentPosition;
btQuaternion _currentRotation;
btVector3 _targetPosition;
glm::vec3 _lastPosition;
btScalar _lastStepUp; btScalar _lastStepUp;
///keep track of the contact manifolds ///keep track of the contact manifolds
btManifoldArray _manifoldArray; btManifoldArray _manifoldArray;
bool _touchingContact; bool _touchingContact;
btVector3 _floorNormal; // points from object to character
bool _enabled; bool _enabled;
bool _isOnGround; bool _isOnGround;
@ -90,9 +93,6 @@ protected:
btScalar _stepDt; btScalar _stepDt;
uint32_t _pendingFlags; uint32_t _pendingFlags;
glm::vec3 _shapeLocalOffset;
glm::vec3 _boxScale; // used to compute capsule shape
btDynamicsWorld* _dynamicsWorld = NULL; btDynamicsWorld* _dynamicsWorld = NULL;
btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal);

View file

@ -36,8 +36,8 @@ PhysicsEngine::~PhysicsEngine() {
delete _collisionDispatcher; delete _collisionDispatcher;
delete _broadphaseFilter; delete _broadphaseFilter;
delete _constraintSolver; delete _constraintSolver;
// delete _dynamicsWorld; delete _dynamicsWorld;
// delete _ghostPairCallback; delete _ghostPairCallback;
} }
// begin EntitySimulation overrides // begin EntitySimulation overrides

View file

@ -535,10 +535,13 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit
} }
void DeferredLightingEffect::setAmbientLightMode(int preset) { void DeferredLightingEffect::setAmbientLightMode(int preset) {
if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { if ((preset >= 0) && (preset < model::SphericalHarmonics::NUM_PRESET)) {
_ambientLightMode = preset; _ambientLightMode = preset;
auto light = _allocatedLights.front(); auto light = _allocatedLights.front();
light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET)); light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET));
} else {
// force to preset 0
setAmbientLightMode(0);
} }
} }

View file

@ -2372,7 +2372,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
bool forceRenderSomeMeshes) { bool forceRenderMeshes) {
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);
int meshPartsRendered = 0; int meshPartsRendered = 0;
@ -2395,7 +2395,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
args, locations, skinLocations); args, locations, skinLocations);
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
args, locations, skinLocations, forceRenderSomeMeshes); args, locations, skinLocations, forceRenderMeshes);
GLBATCH(glUseProgram)(0); GLBATCH(glUseProgram)(0);
return meshPartsRendered; return meshPartsRendered;
@ -2403,7 +2403,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) { Locations* locations, SkinLocations* skinLocations, bool forceRenderMeshes) {
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);
auto textureCache = DependencyManager::get<TextureCache>(); auto textureCache = DependencyManager::get<TextureCache>();
@ -2439,21 +2439,14 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
// if we got here, then check to see if this mesh is in view // if we got here, then check to see if this mesh is in view
if (args) { if (args) {
bool shouldRender = true; bool shouldRender = true;
bool forceRender = false;
args->_meshesConsidered++; args->_meshesConsidered++;
if (args->_viewFrustum) { if (args->_viewFrustum) {
// NOTE: This is a hack to address the fact that for avatar meshes, the _calculatedMeshBoxes can be wrong shouldRender = forceRenderMeshes ||
// for some meshes. Those meshes where the mesh's modelTransform is the identity matrix, and will have args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
// incorrectly calculated mesh boxes. In this case, we will ignore the box and assume it's visible.
if (forceRenderSomeMeshes && (geometry.meshes.at(i).modelTransform == glm::mat4())) {
forceRender = true;
}
shouldRender = forceRender || args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
if (shouldRender && !forceRender) { if (shouldRender && !forceRenderMeshes) {
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter()); float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(), shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
distance); distance);

View file

@ -460,14 +460,14 @@ private:
bool renderCore(float alpha, RenderMode mode, RenderArgs* args); bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
bool forceRenderSomeMeshes = false); bool forceRenderMeshes = false);
void setupBatchTransform(gpu::Batch& batch); void setupBatchTransform(gpu::Batch& batch);
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned); QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
RenderArgs* args, Locations* locations, SkinLocations* skinLocations, RenderArgs* args, Locations* locations, SkinLocations* skinLocations,
bool forceRenderSomeMeshes = false); bool forceRenderMeshes = false);
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,

View file

@ -1,6 +1,6 @@
// //
// SettingInterface.cpp // SettingInterface.cpp
// // libraries/shared/src
// //
// Created by Clement on 2/2/15. // Created by Clement on 2/2/15.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -9,7 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QThread> #include <QThread>
@ -23,8 +22,16 @@ namespace Setting {
// cleans up the settings private instance. Should only be run once at closing down. // cleans up the settings private instance. Should only be run once at closing down.
void cleanupPrivateInstance() { void cleanupPrivateInstance() {
delete privateInstance; // grab the thread before we nuke the instance
privateInstance = nullptr; QThread* settingsManagerThread = privateInstance->thread();
// tell the private instance to clean itself up on its thread
privateInstance->deleteLater();
privateInstance = NULL;
// quit the settings manager thread and wait on it to make sure it's gone
settingsManagerThread->quit();
settingsManagerThread->wait();
} }
// Sets up the settings private instance. Should only be run once at startup // Sets up the settings private instance. Should only be run once at startup