UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

92 lines (91 loc) 3.96 kB
import {BaseSopOperation} from "./_Base"; import {Float32BufferAttribute} from "three/src/core/BufferAttribute"; import {InputCloneMode as InputCloneMode2} from "../../../engine/poly/InputCloneMode"; export class AttribCopySopOperation extends BaseSopOperation { static type() { return "attribCopy"; } cook(input_contents, params) { const core_group_dest = input_contents[0]; const core_group_src = input_contents[1] || core_group_dest; const attrib_names = core_group_src.attribNamesMatchingMask(params.name); for (let attrib_name of attrib_names) { this.copy_vertex_attribute_between_core_groups(core_group_dest, core_group_src, attrib_name, params); } return core_group_dest; } copy_vertex_attribute_between_core_groups(core_group_dest, core_group_src, attrib_name, params) { const src_objects = core_group_src.objectsWithGeo(); const dest_objects = core_group_dest.objectsWithGeo(); if (dest_objects.length > src_objects.length) { this.states?.error.set("second input does not have enough objects to copy attributes from"); } else { for (let i = 0; i < dest_objects.length; i++) { const dest_geometry = dest_objects[i].geometry; const src_geometry = dest_objects[i].geometry; this.copy_vertex_attribute_between_geometries(dest_geometry, src_geometry, attrib_name, params); } } } copy_vertex_attribute_between_geometries(dest_geometry, src_geometry, attrib_name, params) { const src_attrib = src_geometry.getAttribute(attrib_name); if (src_attrib) { const size = src_attrib.itemSize; const src_points_count = src_geometry.getAttribute("position").array.length / 3; const dest_points_count = dest_geometry.getAttribute("position").array.length / 3; if (dest_points_count > src_points_count) { this.states?.error.set("not enough points in second input"); } const dest_name = params.tnewName ? params.newName : attrib_name; let dest_attribute = dest_geometry.getAttribute(dest_name); if (dest_attribute) { this._fill_dest_array(dest_attribute, src_attrib, params); dest_attribute.needsUpdate = true; } else { const src_array = src_attrib.array; const dest_array = src_array.slice(0, dest_points_count * size); dest_geometry.setAttribute(dest_name, new Float32BufferAttribute(dest_array, size)); } } else { this.states?.error.set(`attribute '${attrib_name}' does not exist on second input`); } } _fill_dest_array(dest_attribute, src_attribute, params) { const dest_array = dest_attribute.array; const src_array = src_attribute.array; const dest_array_size = dest_array.length; const dest_item_size = dest_attribute.itemSize; const src_item_size = src_attribute.itemSize; const srcOffset = params.srcOffset; const destOffset = params.destOffset; if (dest_attribute.itemSize == src_attribute.itemSize) { dest_attribute.copyArray(src_attribute.array); for (let i = 0; i < dest_array_size; i++) { dest_array[i] = src_array[i]; } } else { const points_count = dest_array.length / dest_item_size; if (dest_item_size < src_item_size) { for (let i = 0; i < points_count; i++) { for (let j = 0; j < dest_item_size; j++) { dest_array[i * dest_item_size + j + destOffset] = src_array[i * src_item_size + j + srcOffset]; } } } else { for (let i = 0; i < points_count; i++) { for (let j = 0; j < src_item_size; j++) { dest_array[i * dest_item_size + j + destOffset] = src_array[i * src_item_size + j + srcOffset]; } } } } } } AttribCopySopOperation.DEFAULT_PARAMS = { name: "", tnewName: false, newName: "", srcOffset: 0, destOffset: 0 }; AttribCopySopOperation.INPUT_CLONED_STATE = [InputCloneMode2.FROM_NODE, InputCloneMode2.NEVER];