My camera simply walks through interior walls of a house I built in Blender. Here are the steps I followed -
Modelled a house in Blender.
Applied physics -> collision to interior and the exterior walls of the house
Exported as .obj and .mtl and used it in a-frame
Placed the camera inside the house.
While the camera is able to walk out of the house from inside by walking through walls, it is unable to move back into the house from outside as collision occurs. Also, camera is able to walk through all the interior walls of the house without collision.
I am not sure how to share my blender files.
Here is my code -
<div id="myEmbeddedScene">
<a-scene raycaster-autorefresh physics embedded="">
<a-assets>
<a-asset-item id="house-obj" src="../images/house.obj"></a-asset-item>
<a-asset-item id="house-mtl" src="../images/house.mtl"></a-asset-item>
<a-mixin id="checkpoint"></a-mixin>
<a-mixin id="checkpoint-hovered" color="#6CEEB5"></a-mixin>
</a-assets>
<!-- Player -->
<a-entity camera="userHeight: 0.6"
universal-controls="movementControls: checkpoint, keyboard"
checkpoint-controls="mode: animate"
kinematic-body>
<a-cursor
cursor="fuse: true;"
timeout="10"
position="0 0.1 -3"
geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03;"
material="color: #4CC3D9; shader: flat;">
</a-cursor>
</a-entity>
<!-- Ground -->
<a-grid static-body visible="false"></a-grid>
<!-- Obstacles -->
<a-obj-model src="#house-obj" mtl="#house-mtl" scale="0.5 0.5 0.5" rotation="0 0 0" class="clickable" static-body></a-obj-model>
<!-- Lighting -->
<a-light type="ambient" color="#bbb"></a-light>
<!-- <a-light color="#ccc" position="0 30 0" distance="100" intensity="0.4" type="point"></a-light>
<a-light color="#ccc" position="3 10 -10" distance="50" intensity="0.4" type="point"></a-light> -->
</a-scene>
</div>
My codepen - https://codepen.io/nirajupadhyay11/pen/ZaGWdN
https://aframe.io/docs/0.7.0/introduction/faq.html#can-i-prevent-the-camera-from-going-through-obstacles
For non-VR desktop experiences with a gamepad or keyboard controls or for VR scenes where the camera is inside a vehicle, you can add a physics engine to prevent movement through obstacles.
https://github.com/donmccurdy/aframe-physics-system
Related
I'm creating a visual T-Shirt designer where the user can add custom text to a specific position. I develop this tool with Vue.js.
For the drag actions for the custom text I'm using the "vue-draggable-resizable' package for vue.js (https://github.com/mauricius/vue-draggable-resizable) with the following code:
<div v-for="layer of getLayers" class="vconf-create-builder-layer" :key="layer.uid" :style="{ background: 'url(' + getLayerImage(layer) + ') center / contain no-repeat' }">
<template v-for="tile of layer.data">
<VueDragResize :key="tile.uid" v-if="tile.type=='typography'" :parentLimitation="true" :isActive="true" :x="tile.boxPositionX" :y="tile.boxPositionY" :w="tile.editBoxWidth" :h="tile.editBoxHeight" #resizestop="updateTypoBoxSize($event, layer, tile)" #dragstop="updateTypoBoxPosition($event, layer, tile)">
<h2 class="typographyTextPreview" :style="{'font-size': tile.fontSize + 'px', 'line-height': tile.lineHeight + 'px', color: tile.fontColor}">{{tile.text ? tile.text : "Please enter an initial text in the settings"}}</h2>
</VueDragResize>
</template>
</div>
To save the position of the text I'm using the dragstop event. There I get the x and y coordinates relative to the parent. My parent is the t-shirt itself, embedded in a DIV container as background-image with background-size: contain. You can see it in the code above.
So when I resize the browser window, the t-shirt becomes smaller proportionally. The problem: The text layer changes the position. It makes sense, because the x and y coordinates are static values in pixel.
Image examples with resized browser window:
What would be the right way to be sure that the text layer always has the same position relative to the parent with a background image embedded, without to define the image with static pixel size?
In I'd like to get user webcam as a simple background (== no tracking, markers...)
With the following code I got it, but there's no shadow on the webcam background.
I guess I should not use the aframe-ar.js, and I can see this example showing webcam mapped on a cube :
webcam as aframe texture
But how to get the webcam as a simple background? And then how to get shadows visible on this background?
<html>
<head>
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script><!-- Master file for aframe (== a-scene) -->
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script><!-- display webcam -->
<script src="../js/play-all-model-animations.js"></script><!-- play animation -->
<script src="../js/aframe-orbit-controls.min.js"></script><!-- orbit cam target -->
<script src="../js/aframe-extras.js"></script><!-- pour cub-env-map -->
</head>
<body>
<a-scene vr-mode-ui="enabled: false" embedded>
<a-assets>
<a-asset-item id="toy" src="../assets/toyDrummerSolo-03.glb"></a-asset-item>
</a-assets>
<a-entity gltf-model="../assets/toyDrummerSolo-03.glb" play-all-model-animations="" shadow="" id="gltf">
</a-entity>
<a-entity camera look-controls orbit-controls="target: 0 1 0; minDistance: 0.5; maxDistance: 60; initialPosition: 0 5 5"></a-entity>
<a-entity id="keylight" light="type:point;intensity:2;castShadow:true;shadowCameraFar:100;shadowBias:-0.001;shadowMapHeight:2048;shadowMapWidth:2048;" position="2.40512 2.77634 2.73113"></a-entity>
<a-entity id="ambient" light="type:hemisphere;color:#e5fdff;groundColor:#ffffff;intensity:0.5" visible=""></a-entity>
</a-scene>
<!-- no shadow on the webcam background -->
</body>
</html>
There a couple of questions here, not sure which ones are resolved, so let me address the title:
1. non a-frame background
Without a <a-sky>, or background <a-scene background=""> defined - any elements below the scene will be visible. Like here:
<img src="background-image">
<a-scene>
<a-box></a-box>
</a-scene>
1a. webcam background
Almost the same as above, but instead as an img you need a video element:
<video></video>
// after the page is loaded:
// navigator.mediaDevices.getUserMedia({video: true})
// .then(stream => {
// video.srcObject = stream;
// video.play();
// })
Adjusting the sizes, for the scene to match the video can be tricky, but it's not the issue here.
2. background shadows
As the camera background has no physical surfaces to receive shadows - we'll have to imitate them. For example the shadows can be cast on an invisible <a-plane> element. Three.js has a special material for this: ShadowMaterial. A simplified example could look like this:
<video>
<a-scene>
<a-box shadow>
<a-plane rotation="-90 0 0" apply-shadowmaterial></a-plane>
</a-scene>
with a simple custom component:
AFRAME.registerComponent("apply-shadowmaterial", {
init: function() {
// grab the mesh
let mesh = this.el.getObject3D("mesh");
// keep the reference to the old material
let tmp = mesh.material;
// assign the new material
mesh.material = new THREE.ShadowMaterial({ opacity: 0.6 });
mesh.receiveShadow = true;
// free memory
tmp.dispose();
}
});
Check it out here(sloppy resizing, but i think this is not what matters here :))
With Quasar, I'm trying to put q-breadcrumb-el inside a q-toolbar.
However, the breadcrumb text is invisible, because it's the same color as the background of the toolbar (the theme primary color).
Quasar components intended for use in the toolbar (e.g q-toolbar-title) render text in a color that contrasts correctly.
I can hard-code the color in my template, but that will fail if the theme primary color is changed to a light color.
Is there a common idiom to say something like, "contrasting with background color" or "same color as text in xxx element" in Quasar (or Vue, or vanilla CSS)? (I.e, something that all the cool kids just know?)
How can I determine how q-toolbar-title does it?
<q-toolbar>
<q-toolbar-title>Wiki Page</q-toolbar-title> <!-- <== white text on primary color background -->
<q-breadcrumbs>
<q-breadcrumbs-el
v-for="section in sections"
:key="section.label"
:label="section.label"
:to="section.path"
class="text-white" <!-- <== works, but is fragile -->
></q-breadcrumbs-el>
</q-breadcrumbs>
</q-toolbar>
If I get want you mean.
Add a CSS text-stroke property the color should be black or white only.
So as to differentiate the text color from the toolbar color.
<q-toolbar>
<q-toolbar-title>Wiki Page</q-toolbar-title> <!-- <== white text on primary color background -->
<q-breadcrumbs style="font-size: 20px;-webkit-text-stroke: 0.4px black;">
<q-breadcrumbs-el
v-for="section in sections"
:key="section.label"
:label="section.label"
:to="section.path"
class="text-white" <!-- <== works, but is fragile -->
></q-breadcrumbs-el>
</q-breadcrumbs>
</q-toolbar>
I am using gmaps4jsf jar and trying to display marker on map. Marker is displaying fine but not automatic zoom functionality. every time i need to vary zoom value so is there any option in gmaps4jsf so that we can get auto zoom functionality?
<m:map latitude="10.132567" longitude="10.132567" height="400px" width="400px" zoom="6">
<ui:repeat var="p" value="#{pointBean.points2}" varStatus="status" offset="0" step="1" size="#{pointBean.points2.size()}">
<m:marker latitude="#{p.latitude}" longitude="#{p.longitude}" >
<m:htmlInformationWindow htmlText="#{p.latitude}-#{p.longitude}" />
</m:marker>
</ui:repeat>
</m:map>
Thanks in advance!!!
You need to put autoReshape="true" in map tag like,
<m:map autoReshape="true">.....</map>
autoReshape just do adjust marker on map and you will get marker display only.
In order to have markers that are clickable and marker shadows that are not, I'm setting up two geoxml3 parsers, one for the markers and one for the shadows. That works, but I'm hoping that having two layers will also let me keep the shadow of one marker from falling on another marker. It's a subtle thing, but having a visually horizontal shadow overlaid on a visually vertical marker undercuts the 3-D effect. And in a cluster of markers, things get pretty murky down among the marker stems.
Now, I get that icons are rendered from north to south, so that an icon will peek over the top of an overlapping icon to the south of it. What I was expecting was that each parser would create its own layer, in the sense that a marker layer would appear entirely in front of a preceding shadow layer, with no shadow falling on any marker. It sure looks, though, like the parsers are working north to south down both "layers" at the same time. It seems like for each point they render the shadow image and then the corresponding marker image before moving down to the next point. If the next marker is pretty close to the southwest of the previous marker, its shadow image falls onto that previous marker.
To make sure I wasn't seeing some sort of illusion, as an exercise I put together a map with a couple of big, overlapping shadowed markers. What I'd hope for would be to have the images layered, bottom to top:
East Greenland Shadow
Greenland Shadow
East Greenland Marker
Greenland Marker
Instead, they appear to be layered:
East Greenland Shadow
East Greenland Marker
Greenland Shadow
Greenland Marker
with the Greenland Shadow falling on the East Greenland Marker.
So, can I get all of the markers to appear, collectively, in front of all the shadows? I can't track it down at the moment, but I believe I saw a list of standard Google Maps layers somewhere, which included something like a non-clickable "Shadow Layer". When I create a google.maps.KmlLayer with standard icons, the API automatically pulls up the corresponding shadow images and places those on what I guess is the Shadow Layer, which sits entirely behind the KmlLayer I asked for.
In my current project, I need a geoxml3 marker layer, so I can programatically access the placemarks. Since I can actually work with 32x32 icons, in this case I can just fall back to using a KmlLayer for the shadows, but for future reference it would be great to have the option of a non-clickable geoxml3 layer that sits entirely behind a clickable layer. Is there a way to do that? Would that be a matter of somehow rendering onto that Google Maps Shadow Layer?
Here's the script:
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(71, -45),
zoom: 4,
preserveViewport: true
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
// Shadow Layer
var shadow = new geoXML3.parser({
map: map,
zoom: false,
markerOptions: {clickable: false}
});
shadow.parse('greenland_shadow_5.kml');
// Marker Layer
var blues = new geoXML3.parser({
map: map,
singleInfoWindow: true,
zoom: false,
suppressDirections: true,
markerOptions: {
shape: {
type: 'circle',
coords: [38,38,38]
}
}
});
blues.parse('greenland_5.kml');
}
google.maps.event.addDomListener(window, 'load', initialize);
The two KML files are identical except for the IconStyles:
<IconStyle>
<Icon>
<href>bluemarker_76x128.png</href>
<scale>1.0</scale>
</Icon>
<hotSpot x="38" y="0" xunits="pixels" yunits="pixels" />
</IconStyle>
versus:
<IconStyle>
<Icon>
<href>markershadow_188x128.png</href>
<scale>1.0</scale>
</Icon>
<hotSpot x="96" y="0" xunits="pixels" yunits="pixels" />
</IconStyle>
You could take the "MarkerShadow" class and use it to make a layer of just shadows. and make a layer with just markers: proof of concept
- disadvantage: processes the same KML twice.
I can think of 4 options for you:
Put your shadows in a separate KML file and display them using the native google.maps.KmlLayer, that should put them underneath all the google.maps.Marker objects, which is what geoxml3 uses to render the icons. The issue with KmlLayer is that it does not support scaling, all icons are scaled to 64x64 and if they can't be, they are replaced by the default blue icon. KmlLayer is rendered in the overlayLayer pane.
create custom "markers" using Custom Overlays that support combining a marker image with a shadow image. Used to be supported natively by the Google Maps Javascript API v3, but they removed that functionality with the "visual refresh". It looks like the "shadowPane" still exists (at least for now), you could put all the shadows there.
overlayShadow contains the marker shadows. It may not receive DOM events. (Pane 2).
mapPanes reference
Use the zIndex option of the google.maps.Marker object to put the shadows below the markers. Put all the shadows at zIndex = 0 (so they are on the bottom, then use an algorithm to put the markers in their default orientations:
zIndex: Math.round(latlng.lat()*-100000)<<5
"manually" add a shadow to the markers in a custom "createMarker" function (append the shadow image to the shadowPane)
proof of concept marker with shadow