I've applied transparency in maya and export it as dae, but when I'm converting dae to gltf, transparency is not visible. Can anyone tell me how to achieve transparency in gltf file?
materail used in .gltf file
"materials": {
"small_walls_lambert2-fx": {
"name": "small_walls_lambert2",
"technique": "technique0",
"values": {
"ambient": [
0,
0,
0,
1
],
"diffuse": "texture_small_walls_file1-image",
"emission": [
0,
0,
0,
1
]
}
},
fo your reference i am attaching sample gltf 3d model.
My requirement is walls should be in transaparant, it is achived in maya but not visible when coming to gltf(cesium). Is there any way to achieve this by editing gltf file.
The transparency factor is usually in the range [0,1]. Maya does always export a transparency factor of 1.0, which implies full transparency.
Here is my code from the FBX->glTF converter
web::json::value gltfWriter::WriteMaterialTransparencyParameter (
const utility::char_t *pszName,
FbxPropertyT<FbxDouble> &property, FbxPropertyT<FbxDouble3> &propertyColor, FbxProperty &propertyOpaque,
web::json::value &values, web::json::value &techniqueParameters
) {
web::json::value ret =web::json::value::null () ;
double value =1. ;
if ( propertyOpaque.IsValid () ) {
value =1.0 - propertyOpaque.Get<double> () ;
} else {
if ( !property.IsValid () )
return (ret) ;
value =property.Get () ;
if ( propertyColor.IsValid () ) {
FbxDouble3 color =propertyColor.Get () ;
value =(color [0] * value + color [1] * value + color [2] * value) / 3.0 ;
}
}
if ( !GetIOSettings ()->GetBoolProp (IOSN_FBX_GLTF_INVERTTRANSPARENCY, false) )
value =1.0 - value ;
values [pszName] =web::json::value::number (value) ;
techniqueParameters [pszName] =web::json::value::object ({ { U("type"), IOglTF::FLOAT } }) ;
return (ret) ;
}
What is does is to check if there is an Opaque property set. If not use the TransparencyFactor and TransparencyColor to determine the glTF transparency.
value =(color [0] * value + color [1] * value + color [2] * value) / 3.0 ;
You material definition above does not define any transparency, so you would need to add something like this:
"transparency": 1,
"transparent": [0,
0,
0,
1]
and handle the parameter in your shader as well.
Related
I have a code as below. Although I update the sphere position with every frame (useFrame), it does not reflect on my scene. Can someone please help me understand why it will not work.
PS : I am new to this and am trying to do some quick proof of concepts.
function Marble() {
const controls = useControls()
const [sphereRef, sphereApi] = useSphere(() => ({
type: "Dynamic",
mass: 1,
position: [0, 2, 0]
}));
//sphereApi.position.set([0,0,0])
//console.log("SHM sphereAPI position", sphereRef.current.position);
useFrame(() => {
const { forward, backward, left, right, brake, reset } = controls.current
if (forward == true) {
console.log("sphereRef position", sphereRef.current.position);
console.log("sphereAPI position", sphereApi.position);
//console.log("model position", model.current.position)
// sphereApi.velocity.set(2,2,2);
sphereApi.position.set(5,0,0)
// sphereRef.current.position.set(5,0,0);
}
})
return (
<mesh ref={sphereRef} castShadow>
<sphereBufferGeometry attach="geometry" args={[1, 32, 32]}></sphereBufferGeometry>
<meshStandardMaterial color="white" />
</mesh>
);
})
( See it online: Stackblitz )
Doing sphereApi.position.set(5,0,0) on every frame, just sets the sphere position to x=5 on every frame.
So you should create a state first to store the x position, then update it on every frame to +=5, and then set the sphere position to it:
const [sphereX, setSphereX] = useState(0);
useFrame(() => {
setSphereX((sphereX) => sphereX + 0.05); // set state x position to +0.05 (5 is fast)
sphereApi.position.set(sphereX, 0, 0); // apply the state to the sphere position
});
Also make sure to use allowSleep={false} since changing position directly isn't a physical movement, so the physical scene may get sleep.
Online: Stackblitz
Trying to animate a bunch of objects to their positions, and useSpring works for me (for single element), but useSprings is not for 3 objects.
Here is demo (mousedown red ball):
https://codesandbox.io/s/try-to-do-zgit5?file=/src/App.js:1254-1857
Here is code:
// working for me
const { z } = useSpring({
from: { z: 0 },
to: { z: mousedown ? 0 : -0.5 }
})
// not working with state change
// although working with a
// loop: { reverse: true, delay: 0 },
// but not accounting state changes
const [springs] = useSprings(3, (i) => ({
from: { x: 0, y: i * 2 - 2 },
to: { x: mousedown ? 0.5 : -0.5, y: i * 2 - 2 + 1 },
}))
and the elements:
// works
<a.mesh position-z={z}
onPointerDown={(e) => setMousedown(true)}
onPointerUp={(e) => setMousedown(false)}>...</a.mesh>
// not changing positions with state
{springs.map(({ x, y }, index) => (
<a.mesh position-x={x} position-y={y} key={`0${index}`}>...</a.mesh>
))}
As im new to react-spring, this might be a ridiculous simple problem, but im just stuck with this myself now
Solved thanx to Paul Henschel in this sandbox https://codesandbox.io/s/try-to-do-forked-gwy21?file=/src/App.js , addition of [mousedown] dependency parameter to useSprings hook was needed.
I am using d3 v5.9.2, dc v3.0.12 to render a line chart but the ticks in x-axis seems to be having some issue. The data supplied has to be plotted with date along x Axis and value along y-axis since it's a timeline graph.
const line = lineChart(divRef);
const crossfilterDimension = dx.dimension(dimension);
const firstRecord = crossfilterDimension.bottom(1)[0];
const lastRecord = crossfilterDimension.top(1)[0];
line
.dimension(crossfilterDimension)
.x(
scaleTime().domain([
firstRecord[Object.keys(firstRecord)[0]],
lastRecord[Object.keys(lastRecord)[0]]
])
)
.xUnits(timeYear)
.xAxisLabel(xAxis.label)
.yAxisLabel(yAxis.label)
.renderDataPoints({ radius: 2, fillOpacity: 0.8, strokeOpacity: 0.0 })
.group(
count
? crossfilterDimension.group().reduceCount()
: crossfilterDimension.group().reduceSum(group)
);
line
.yAxis()
.ticks(yAxis.ticks)
.tickFormat(yAxis.tickFormat);
return line;
I got a scenario where in I need to display value for every stack in stacked multi-bar chart - nvd3 graph as we can display value in discrete value - nvd3 graph.
I understand, 'showvalue' is used in discrete bar controller, can we use showvalue in stacked graph, if not please suggest with an alternative solution.
Thanks in advance
Currently isn't possible. That option is available only in the discrete bar chart.
From the maintainer:
We don't have this ability. Stacked/Grouped charts also have complex animations making this a tricky thing to solve. We use tooltips instead.
Source https://github.com/novus/nvd3/issues/150
If you want to do this you need to make your own implementation using d3. There is a good example here http://plnkr.co/edit/BNpAlFalKz0zkkSszHh1?p=preview. It's using the angular wrapper but it's a good starting point.
var app = angular.module('app', ['nvd3ChartDirectives']);
app.controller('chartCtrl', function($scope, $timeout) {
var ANIMATION_TIME = 1500,
countSeriesDisplayed = 2,
promise,
labels = ["label1", "label2", "label3", "label4", "label5"];
$scope.isStacked = false;
// Example data
$scope.chartData = [{
"key": "Series 1",
"values": [
[0, 10],
[1, 20],
[2, 30],
[3, 40],
[4, 50]
]
}, {
"key": "Series 2",
"values": [
[0, 10],
[1, 40],
[2, 60],
[3, 20],
[4, 40]
]
}];
/* To add labels, images, or other nodes on the created SVG, we need to wait
* for the chart to be rendered with a callback.
* Once the chart is rendered, a timeout is set to wait for the animation to
* finish.
*
* Then, we need to find the position of the labels and set it with the
* transform attribute in SVG.
* To do so, we have to get the width and height of each bar/group of bar
* which changes if stacked or not
*
*/
// Callback called when the chartData is assigned
$scope.initLabels = function() {
return function(graph) {
promise = $timeout(function() {
var svg = d3.select("svg"),
lastRects, rectWidth,
heightForXvalue = []; // Used for grouped mode
// We get one positive rect of each serie from the svg (here the last serie)
lastRects = svg.selectAll("g.nv-group").filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).selectAll("rect.positive");
if ($scope.isStacked) {
// If stacked, we get the width of one rect
rectWidth = lastRects.filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).attr("width");
} else {
// If grouped, we need to get the greatest height of each bar
var nvGroups = svg.selectAll("g.nv-group").selectAll("rect.positive");
nvGroups.each(
function(d, i) {
// Get the Min height space for each group (Max height for each group)
var rectHeight = parseFloat(d3.select(this).attr("y"));
if (angular.isUndefined(heightForXvalue[i])) {
heightForXvalue[i] = rectHeight;
} else {
if (rectHeight < heightForXvalue[i]) {
heightForXvalue[i] = rectHeight;
}
}
}
);
// We get the width of one rect multiplied by the number of series displayed
rectWidth = lastRects.filter(
function(d, i) {
return i == countSeriesDisplayed - 1;
}).attr("width") * countSeriesDisplayed;
}
// We choose a width equals to 70% of the group width
var labelWidth = rectWidth * 70 / 100;
var groupLabels = svg.select("g.nv-barsWrap").append("g");
lastRects.each(
function(d, index) {
var transformAttr = d3.select(this).attr("transform");
var yPos = parseFloat(d3.select(this).attr("y"));
groupLabels.append("text")
.attr("x", (rectWidth / 2) - (labelWidth /2)) // We center the label
// We add a padding of 5 above the highest rect
.attr("y", (angular.isUndefined(heightForXvalue[index]) ? yPos : heightForXvalue[index]) - 5)
// We set the text
.text(labels[index])
.attr("transform", transformAttr)
.attr("class", "bar-chart-label");
});
}, ANIMATION_TIME);
}
};
// Tooltips
$scope.toolTipContentFunction = function () {
return function (key, x, y, e, graph) {
return labels[x];
}
};
$scope.$on('$destroy', function () {
// Cancel timeout if still active
$timeout.cancel(promise);
});
});
UPDATE:
I've created a gist that could help you to implement this by yourself.
https://gist.github.com/topicus/217444acb4204f364e46
I have ExtJs 4 Area chart with Time serie. I'd like user to be able to horizontally select part of chart and then obtain higher density data from server adequately. Problem is I can't get boundary dates from selection. I've got:
var chart = Ext.create('Ext.chart.Chart', {
store: store,
enableMask: true,
mask: 'horizontal',
listeners: {
select: {
fn: function(me, selection) {
console.log(arguments); // selection = Object { height: 218, width: 117, x: 665, y: 123 }
}
},
...
But select listener provides only pixel data. Is there some way to get boundary axis data (e.g. { from: 2013-08-01, to: 2013-08-20 } or some way to unproject pixels to values? I'm desperade I would say it's such a basic thing but can't find solution anywhere. Thanks in advance.
Well.. it probably doesn't exists a method for this. After digging into source code I've utilized lines from chart.setZoom() method to create function for manual unprojecting of mask selection to X axis data:
var unprojectXAxis = function(chart, selection) {
zoomArea = {
x : selection.x - chart.el.getX(),
width : selection.width
};
xScale = chart.chartBBox.width,
zoomer = {
x : zoomArea.x / xScale,
width : zoomArea.width / xScale
}
ends = chart.axes.items[0].calcEnds();
from = (ends.to - ends.from) * zoomer.x + ends.from;
to = (ends.to - ends.from) * zoomer.width + from;
return { from: new Date(from), to: new Date(to) };
}