Three.js: Apply a scale to all children nodes
I need to reset the scale on a specific node while keeping all descendant nodes identical in the world.
In my JSFiddle I have the following tree:
Root => R => C => C2
The scale is set on R. When I apply the scale on descendants, the direct child position is still right, but not its own childs, so I must be missing something
function bakeScale(object) {
for (var i = 0 ; i < object.children.length; i++) {
var c = object.children[i];
c.position.multiply(object.scale);
c.scale.multiply(object.scale.applyQuaternion(object.quaternion));
c.scale.x = Math.abs(c.scale.x);
c.scale.y = Math.abs(c.scale.y);
bakeScale(c);
}
object.scale.set(1,1,1);
object.updateMatrix();
object.updateMatrixWorld();
}
I'm aware of Object3D.attach() but I don't want the change the tree structure
PS: bonus points for a method that would also work with baking the rotation
See also questions close to this topic
- How do I find the coordinates of a point on a circle in PyGame?
-
How do I calculate the exact number of days old in Small Basic
So, for my school assignment, I have to build an ageing program that needs to calculate the number of days old (age in days). It needs to be in the text window, not the graphic window.
I have this:
Dayslived = (bob * 12 + (clock.month - month + 12)) * 30.4 + (clock.Day - day)
it works but if you enter to give the program a month (as in a number 4 = April) which is before the current month then it does not work.
How do I fix this?
-
how to print a list of a function in tabulated form
I am typing a code to produce values for integration via the Trapezoidal method and Simpson's rule as well as the absolute difference of these values given an input 'n'. The 'n' input is a function in itself of n = 2 ** i if i is in the range (1, 19).
I am struggling to tabulate my answers for all values of n. My code only gives the table for one value of n. i.e.
n Trapezoidal Simpson Absolute Difference --- ------------- --------- --------------------- 16 -0.594187 -0.587389 0.00679814
however, I want my table to look like this
and so on and so forth until n = 524288.
Below is my code. Please assist me on where I am going wrong.
from numpy import arange import numpy as np from numpy import subtract from tabulate import tabulate from math import cos, sin, pi, def trapezoidal(f, n, a, b): h = (b-a)/ n x = a + arange(n + 1) * h integral_approx = 0.5 * h * (f(x[0]) + f(x[n])) for i in arange(1, n): integral_approx = integral_approx + h * f(x[i]) return integral_approx def simpson(f, n, a, b): if n % 2 is not 0: return None h = (b - a)/n first = f(a) last = f(b) x = a summ = 0 for i in range(n - 1): x += h value = f(x) if i % 2 == 0: summ += 4 * value else: summ += 2 * value integral_approx = (h/3) * (first + summ + last) return integral_approx a = 0.1 b = pi/2 f = lambda x: (cos(x)*np.log(sin(x)))/((sin(x)**2) + 1) for i in range(1, 20): n = 2**i absdiff = abs(subtract(trapezoidal(f, n, a, b), simpson(f, n, a, b))) d = [[n, trapezoidal(f, n, a, b), simpson(f, n, a, b), absdiff]] print(tabulate(d, headers = ["n", "Trapezoidal", "Simpson", "Absolute Difference"]))
-
Python: Implementing an n-dimensional matrix/tensor as one dimensional list of elements
So, I have a matrix/tensor class. It consists of a one dimensional numpy array filled with elements and a second array denoting the shape of the matrix.
So for example the matrix:
1 4 2 5 3 6
would have the elements [1,2,3,4,5,6] and shape [3,2]
I'm a little stuck right off the bat. Right now I want to write a getter/setter function and implement mathematical operations like multiplication, but I have no idea how to do it.
I have a rough idea for a setter, with using modulo, but I don't know how I can make it behave dynamically for n-dimensions, since the formula would have to be extended for higher dimensions, right?
As for mathematical operations, I'm absolutely clueless how to do it efficently, without getting stuck in endless nested for-loops
I don't expect anyone to write my code for me, but I was hoping to get some helpful links to similar approaches, since I couldn't find any myself.
-
elements are being added to every row when inserting into a row for a 2D array that has been filled with empty Arrays
I am creating a new matrix where I want to take the rows of the original matrix and make them into columns as well as take the columns of the original matrix and make them into rows.
so a matrix of :
[[1,2] [3,4] [[1,3,5] [5,6]] turns into [2,4,6]]
When I initialize the new matrix while using the fill() method to create my rows, the insertions duplicate for every row when inserting into a row.
const arrOne = [[1,2,3],[4,5,6],[7,8,9]] var transpose = function(matrix) { const transposedArr = new Array(matrix[0].length).fill(new Array()); // initializes array to [ [], [], [] ] //iterate through row for(let i = 0; i < matrix.length; i++) { //iterate through columns at row for(let j = 0; j < matrix[i].length; j++) { transposedArr[j].push(matrix[i][j]) } } return transposedArr; }; console.log(transpose(arrOne));
This will print
[ [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], ]
when I initialize my array using a for loop, I do not get duplicate entries
const arrOne = [[1,2,3],[4,5,6],[7,8,9]] var transpose = function(matrix) { const transposedArr = [] // initializing using const transposedArr = Array() also works! for(let i = 0; i < matrix[0].length; i++) { // initializes array to [ [], [], [] ] transposedArr.push(new Array()) } //iterate through row for(let i = 0; i < matrix.length; i++) { //iterate through columns at row for(let j = 0; j < matrix[i].length; j++) { transposedArr[j].push(matrix[i][j]) } } return transposedArr; }; console.log(transpose(arrOne));
This will print
[ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ]
ASK: Why is it that when I initialize the array using the fill() method, it is duplicating my insertions for each row?
I came across this issue when working on this Leetcode problem: https://leetcode.com/problems/transpose-matrix/
I also tested this code in repl.it to make sure it wasn't an issue in Leetcode's environment.
-
Building a Binary matrix out of a data frame after converting values of one column into rows in R
I want to build a binary matrix from a data frame that looks like the following; two columns one has the cell type and the other contains markers.
Markers Cell type "CD3D, CD3E, CD3G, CD4" Peripheral blood_Normal_T helper cell "CD3D, CD3E, CD3G, PTPRC" Peripheral blood_Normal_Memory T cell "IL2RA, CD3D, CD3E, CD3G, CD4, FOXP3" Peripheral blood_Normal_Regulatory T (Treg) cell "CD3D, CD3E, CD3G, CD4, IFNG" Peripheral blood_Normal_T helper1 (Th1) cell "CD3D, CD3E, CD3G, CD4, IL4" Peripheral blood_Normal_T helper2 (Th2) cell "CD3D, CD3E, CD3G, CD4, IL17RA" Peripheral blood_Normal_T helper17 (Th17) cell "PROM1, PECAM1, CD34, PTPRC" Peripheral blood_Gastric Cancer_Endothelial progenitor cell "PROM1, PECAM1, CD34, PTPRC" Peripheral blood_Gastric Cancer_Endothelial cell CD14 Blood_Normal_Monocyte NRP1 Blood_Normal_Plasmacytoid dendritic cell GP1BA Blood_Normal_T helper cell
I would like the final output to take the following structure. so each cell type is a column on its own and each marker which some times comes single value and some other times they are several markers separated by a comma as rows. Finally, the matrix values for each cell type indicate 1 if the marker existed in the markers columns for this specific cell type or 0 if not.
Blood_Normal_T helper cell Peripheral blood_Gastric Cancer_Endothelial progenitor cell PROM1 0 1 PECAM1 0 1 CD34 0 1 PTPRC 0 1 GP1BA 1 0 .....
Thanks for the help
-
WebXR: How can I adjust the eye-separation in Three.js and avoid cyclopic vision?
I can't find any info, and surprisingly all Three.js and WEBGL examples I've seen render a single camera with no separate adjustment, like setting the correct parallax is ...something optional and insignificant!
Fortunately the webxr api provides this functionality but it's not clear to me how to do this in Three.js: https://immersive-web.github.io/webxr/#xrview-interface
The only part of three.js I've found that comes close to this is WebXRManager but apparently it doesn't provide the required functionality and it needs a hack, or extension: https://github.com/mrdoob/three.js/blob/master/src/renderers/webxr/WebXRManager.js
Any hints how to do this in Three.js?
-
Using a GLTF model as the Scene in Three.js
I am new to Three.js. I am having issues using a gltf model as the actual scene and not part of the scene in three.js. The gltf model is an apartment. I want the scene to load from inside the apartment and not outside the apartment. the controls should work within the apartment too. So far, I have loaded the model on the scene but I can't get the scene to render from inside the model.
Here is my code in Typescript and also JavaScript been at it for weeks now. Any help will be much appreciated. Thank you so much.
Typescript code
import * as THREE from '/build/three.module.js' import { OrbitControls } from '/jsm/controls/OrbitControls' import { GLTFLoader } from '/jsm/loaders/GLTFLoader' import Stats from '/jsm/libs/stats.module' const scene: THREE.Scene = new THREE.Scene() const axesHelper = new THREE.AxesHelper(5) //scene.add(axesHelper) var light = new THREE.SpotLight(); light.position.set(5, 5, 5) scene.add(light); const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) camera.position.z = 2 const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer() //renderer.physicallyCorrectLights = true //renderer.shadowMap.enabled = true renderer.outputEncoding = THREE.sRGBEncoding renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) const loader = new GLTFLoader() loader.load( 'apartment.glb', function (gltf) { // gltf.scene.traverse(function (child) { // if ((<THREE.Mesh>child).isMesh) { // let m = <THREE.Mesh>child // m.receiveShadow = true // m.castShadow = true // } // if ((<THREE.Light>child).isLight) { // let l = <THREE.Light>child // l.castShadow = true // //l.shadow.bias = -.003 // l.shadow.mapSize.width = 2048 // l.shadow.mapSize.height = 2048 // } // }) scene.add(gltf.scene); }, (xhr) => { console.log((xhr.loaded / xhr.total * 100) + '% loaded') }, (error) => { console.log(error); } ); window.addEventListener('resize', onWindowResize, false) function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) render() } const stats = Stats() document.body.appendChild(stats.dom) var animate = function () { requestAnimationFrame(animate) controls.update() render() stats.update() }; function render() { renderer.render(scene, camera) } animate();
JavaScript code
import * as THREE from '/build/three.module.js'; import { OrbitControls } from '/jsm/controls/OrbitControls'; import { GLTFLoader } from '/jsm/loaders/GLTFLoader'; import Stats from '/jsm/libs/stats.module'; const scene = new THREE.Scene(); const axesHelper = new THREE.AxesHelper(5); //scene.add(axesHelper) var light = new THREE.SpotLight(); light.position.set(5, 5, 5); scene.add(light); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 2; const renderer = new THREE.WebGLRenderer(); //renderer.physicallyCorrectLights = true //renderer.shadowMap.enabled = true renderer.outputEncoding = THREE.sRGBEncoding; renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement); const loader = new GLTFLoader(); loader.load('apartment.glb', function (gltf) { // gltf.scene.traverse(function (child) { // if ((<THREE.Mesh>child).isMesh) { // let m = <THREE.Mesh>child // m.receiveShadow = true // m.castShadow = true // } // if ((<THREE.Light>child).isLight) { // let l = <THREE.Light>child // l.castShadow = true // //l.shadow.bias = -.003 // l.shadow.mapSize.width = 2048 // l.shadow.mapSize.height = 2048 // } // }) scene.add(gltf.scene); }, (xhr) => { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, (error) => { console.log(error); }); window.addEventListener('resize', onWindowResize, false); function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); render(); } const stats = Stats(); document.body.appendChild(stats.dom); var animate = function () { requestAnimationFrame(animate); controls.update(); render(); stats.update(); }; function render() { renderer.render(scene, camera); } animate();
-
rendering 1 million boxes in react-three/fiber
I am testing the rendering 1 mil boxes in react-three/fiber. The performance is very slow.
function App() { const boxes = []; for (let i = 0; i < 1000; i++) { const x = Math.random(); const y = Math.random(); const z = Math.random(); const box = ( <mesh position={[x, y, z]}> <boxGeometry args={[0.01, 0.01, 0.01]} /> <meshLambertMaterial color={"red"} /> </mesh> ); boxes.push(box); } return ( <MBox style={{ height: "100vh", width: "100vw" }}> <Canvas camera={{ position: [10, 10, 10] }}> <pointLight position={[15, 15, 15]} /> {boxes} <OrbitControls /> <Stats /> </Canvas> </MBox> ); }
The render is responsive with 1000 boxes (60 FPS). With 10000 boxes, it drops to 7 FPS with a bit lack. The browser dies with 100000 boxes.
The computer dedicated GPU NVIDIA is not utilized at all.
Any idea to improve the performance please?
-
CGAl 3D mesh generation concepts
I am trying to understand some concepts of the CGAL 3D mesh generation. In my particular case I am trying to generate a tetrahedral mesh given a polyhedral mesh. The polyhedral mesh I am using as an example has two unconnected convex regions.
If I understand CGAL documentation correctly, the 3D mesh generation creates a triangulation, which is a tetrhaedral mesh of the convex hull of some points, in this case, of the points in my input polyhedral mesh.
Some of the tetrahedra in the triangulation may be outside of my polyhedral mesh, so what CGAL actually returns when generating the 3D tetrhaedral mesh is an object, called C3T3 in CGAL documentation, which can query if a tetrahedron, facet, segment or point in inside my polyhedral mesh. Is this right?
I have done a small check and I have the following output:
std::cout << "Number of cells in triangulation " << visualMesh.triangulation().number_of_cells() << "\n"; std::cout << "Number of finite cells in triangulation " << visualMesh.triangulation().number_of_finite_cells() << "\n"; std::cout << "Number of cells in complex " << visualMesh.number_of_cells_in_complex() << "\n"; std::cout << "Number of cells in c3t3 " << visualMesh.number_of_cells() << "\n"; std::cout << "Number of facets in complex " << visualMesh.number_of_facets_in_complex() << "\n"; std::cout << "Number of facets in c3t3 " << visualMesh.number_of_facets() << "\n"; std::cout << "Number of vertices in complex " << visualMesh.number_of_vertices_in_complex() << "\n"; std::cout << "Number of coners " << visualMesh.number_of_corners() << "\n";
Number of cells in triangulation 67258 Number of finite cells in triangulation 61266 Number of cells in complex 57433 Number of cells in c3t3 57433 Number of facets in complex 8304 Number of facets in c3t3 8304 Number of vertices in complex 20 Number of coners 20
I dont understand some of these results. First of all, I dont understand the difference between
number_of_facets/cells
andnumber_of_facets/cells_in_complex
. Why do they return the same value and in which case do they return different values.I also have doubts about the
number_of_vertices_in_complex
andnumber_of_corners
. This are apparently returning the amount of vertices there are in my original input mesh. If this is the case, are the number_of_facets/cells[_in_complex]` also returning data about my original input mesh? How do I get the number of vertices I have in the tetrahedra mesh?Finally, if I want to iterate of the cells/facets/points of the tetrahedra mesh, do I have to use c3t3 iterators or the triangulation ones? This is unclear to me, although I think I have to use the c3t3 ones.
-
Brute force to find desired direction with minimum amount of iterations
There's three components to this problem:
- A three dimensional vector A.
- A function F.
- A desired vector B (also three dimensional).
We want to find a vector A that when put through F will produce the vector B.
F(A) = B
F can be anything that somehow transforms or distorts A in some manner. The point is that we want to iteratively call F(A) until B is produced.
The question is:
How can we do this, but with the least amount of calls to F before finding a vector that equals B (within a reasonable threshold)?
-
untity marching cubes fixing normals between chunks
I don't see any info on this anywhere and I'm trying to fix the normal seams between chunks but I have no clue on how to do it in a 3D space. most of the videos and info I have seen relating to fixing normals between chunks are in a 2D mesh format which I have no clue of converting. help would be appreciated and if you need any info on how I structured my project then ill be glad to provide that info, Thanks in advance.