0

Based on a snippet of original r3f-example found in PointCloud.js

Tested by myself, this above original component is able to render pointcloud by pushing individual x y z value into the for-loop in Particle() function.

I modified it and added a `fetch()' method to retrieve a custom data txt file, snippet as shown below,

...

export function Particles() {
  const [positions, colors] = useMemo(() => {
  let positions = [], colors = []
  positions.length = 3
  colors.length = 3

  const HEADER_SIZE = 4;
  let stream, longArray, len;
  let clusterCount ;
  let xy_size ;         
  let clusterSize = [];
  let XY_arr = [];      

  fetch(map)
  .then((r) => r.text())
  .then(text => {
    stream = text.toString().split("\n");     // split by next line
    longArray = stream.slice(2,);             // remove header from main longArray
    len = longArray.length;

    for (let i = 0, count = 0; i < len; i += HEADER_SIZE ) {
      xy_size = longArray.slice((i + HEADER_SIZE - 1), (i + HEADER_SIZE));            
      XY_arr.push(longArray.slice((i + HEADER_SIZE ), (i + HEADER_SIZE + xy_size*2)));    
      console.log(" Points in PointCloud " + count + ": " + xy_size );
      clusterSize.push(xy_size);
      clusterCount = count;
      i += xy_size*2; 
      count ++;          
    }

    for (let i = 0; i < (clusterCount-2); i++) {  
      for (let j = 0; j < clusterSize[i]*2; j+=2) {  
        positions.push( XY_arr[i][j] )
        positions.push(0)
        positions.push( XY_arr[i][j+1] ) 
        colors.push(1)
        colors.push(0.5)
        colors.push(0.5)
        console.log( XY_arr[i][j] );
      }
    }
  }       
)
  return [new Float32Array(positions), new Float32Array(colors)]
}, [])

...
...

, map is the custom text file in string, with single data line-by-line

The fetch() method is able to read a custom pointcloud file into XY_arr as an object of Array(). I have checked that XY_arr[i][j] in the nested-forloop are able to return correct x and z value in console.

Current problem is that no pointcloud being rendered onto <Canvas />

Is the problem caused by position.push() nested loop being inside of 'fetch()' method ? And how to resolve. Thank you.

Lance
  • 35
  • 1
  • 9

1 Answers1

0

better use const [state, set] = useState() and then fetch in useEffect calling "set" when you're done. putting an async fetch request inside useMemo is practically a side-effect in the render function - which isn't good, nor will it work like that.

hpalu
  • 1,357
  • 7
  • 12
  • Thanks for the answer and sorry for late reply. However, I need to parse a array fetched from a dir, and not changing useMemo method. I realized I can actually print out PointCloud with const = { [ARRAY] } . So, is it possible to async fetch and update the ARRAY dynamically? – Lance Apr 01 '20 at 03:23