Skip to content

Commit 96f62f7

Browse files
fix: more bug fixes
1 parent 595e0e1 commit 96f62f7

16 files changed

Lines changed: 319 additions & 121 deletions

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/CourseMapCapture.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default function CourseMapCapture({ worldSize, captureRef }) {
2020

2121
const rt = new THREE.WebGLRenderTarget(size, size, {
2222
colorSpace: THREE.SRGBColorSpace,
23+
samples: 4,
2324
});
2425

2526
const prevFog = scene.fog;

src/components/HolesList.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ export default function HolesList({
168168
<List>
169169
{holeData.map((hole, index) =>
170170
[
171-
hole.number === 10 && <ListSubheader disablePadding>Back Nine</ListSubheader>,
171+
hole.number === 10 && <ListSubheader key={`${hole.number}head`} disablePadding>Back Nine</ListSubheader>,
172172
<HolesListItem
173+
key={hole.number}
173174
hole={hole}
174175
editState={editState}
175176
onSet={onSet}

src/components/TreeLayerList.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ export default function TreeLayerList({
6262
treeLayer.treeConfigs?.map(treeConfig => (
6363
<CustomListItem
6464
button={{
65-
onClick: () => onTreeSelect(treeConfig)
65+
onClick: () => onTreeSelect(treeLayer, treeConfig)
6666
}}
6767
size="small"
6868
selected={selectedTree === treeConfig.id}
6969
// sx={{ p: 1, pl: 3 }}
7070
disablePadding={true}
7171
disableGutters={false}
7272
key={treeConfig.id}
73-
label={treeConfig.filePath.split(/[\/\\]/g).pop()}
73+
label={treeConfig.name || treeConfig.filePath.split(/[\/\\]/g).pop()}
7474
icon={<TreeIcon />}
7575
menuItems={[
7676
{

src/dialogs/EditTerrainDialog.jsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function Terrain({
2222
size = 100
2323
}) {
2424
const internalRef = useRef();
25-
const maxSegments = 2048;
25+
const maxSegments = 1024;
2626
const brushPos = useRef(new THREE.Vector3());
2727

2828
const strength = useMemo(() => {
@@ -382,7 +382,8 @@ export default function EditTerrainDialog(props) {
382382
const heightMap = useRef();
383383
const [heightMapVersion, setHeightMapVersion] = useState(0);
384384
// const [heightMap, setHeightMap] = useState();
385-
const [heightScale, setHeightScale] = useState(project.stats?.heightScale || 100);
385+
386+
const [heightScale, setHeightScale] = useState(project.stats?.heightScale || project.stats?.relief);
386387
const [brushRadius, setBrushRadius] = useState(12);
387388
const [brushStrength, setBrushStrength] = useState(3);
388389
const [smoothStrength, setSmoothStrength] = useState(2);
@@ -455,6 +456,16 @@ export default function EditTerrainDialog(props) {
455456
// setHeightMap(view);
456457
}
457458

459+
useEffect(() => {
460+
const hs = project.stats?.heightScale || project.stats?.relief;
461+
if (typeof hs === 'undefined') {
462+
console.warn('No heightscale on stats!');
463+
return;
464+
}
465+
console.log(`Setting height scale to: ${hs}`);
466+
setHeightScale(hs);
467+
}, [project.stats]);
468+
458469
useEffect(() => {
459470
if (!open) {
460471
return;
@@ -508,6 +519,12 @@ export default function EditTerrainDialog(props) {
508519
>
509520
<SidebarAccordionGroup>
510521
<Accordion expanded={panelExpanded === 'brush'} onChange={handlePanelChange('brush')}>
522+
<AccordionSummary id="brush-header">
523+
<AccordionHeader>Info</AccordionHeader>
524+
</AccordionSummary>
525+
<AccordionDetails sx={{ p: 2 }}>
526+
<Typography>heightScale: {heightScale?.toFixed(3)}</Typography>
527+
</AccordionDetails>
511528
<AccordionSummary id="brush-header">
512529
<AccordionHeader>Brush</AccordionHeader>
513530
</AccordionSummary>

src/dialogs/ExportCourseDialog.jsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ import {
1010
Box,
1111
CircularProgress,
1212
TextField,
13-
MenuItem
13+
MenuItem,
14+
Grid
1415
} from '@mui/material';
1516
import CheckIcon from '@mui/icons-material/CheckCircle';
1617
import { useProject } from '../contexts/Project.jsx';
1718

1819
export default function ExportCourseDialog(props) {
1920
const { project, palette } = useProject();
2021
const { onClose, open, data } = props;
21-
console.log('data', data);
22+
2223
const [jobState, setJobState] = useState({ phase: 'settings', count: 0, progress: 0 });
2324
const [exportSettings, setExportSettings] = useState({ format: 'glb' });
2425

@@ -72,23 +73,28 @@ export default function ExportCourseDialog(props) {
7273

7374
<DialogContent>
7475

75-
{data.mapImage ? (
76-
<img src={data.mapImage} height={200} />
77-
) : null}
78-
7976
{jobState.phase === 'settings' ? (
80-
<Stack spacing={3} sx={{ py: 2 }}>
81-
<TextField
82-
select={true}
83-
fullWidth={true}
84-
label="Format"
85-
onChange={handleFormatChange}
86-
value={exportSettings.format}
87-
>
88-
<MenuItem value="glb">.GLB (Fuse)</MenuItem>
89-
{/* <MenuItem value="obj">.OBJ (Unity)</MenuItem> */}
90-
</TextField>
91-
</Stack>
77+
<Grid container={true} spacing={3}>
78+
<Grid>
79+
{data.mapImage ? (
80+
<img src={data.mapImage} height={200} />
81+
) : null}
82+
</Grid>
83+
<Grid flex={1}>
84+
<Stack spacing={3} sx={{ py: 2 }}>
85+
<TextField
86+
select={true}
87+
fullWidth={true}
88+
label="Format"
89+
onChange={handleFormatChange}
90+
value={exportSettings.format}
91+
>
92+
<MenuItem value="glb">.GLB (Fuse)</MenuItem>
93+
{/* <MenuItem value="obj">.OBJ (Unity)</MenuItem> */}
94+
</TextField>
95+
</Stack>
96+
</Grid>
97+
</Grid>
9298
) : null}
9399

94100

src/lib/ipc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ ipcMain.handle('trees.addLayer', (_event) => project.addTreeLayer());
5252
ipcMain.handle('trees.removeLayer', (_event, layerId) => project.removeTreeLayer(layerId));
5353

5454
ipcMain.handle('trees.import', (_event, treeLayerId) => project.importTree(treeLayerId));
55-
ipcMain.handle('trees.postImport', (_event, treeLayerId, treeConfigId, imageData) => project.postImportTree(treeLayerId, treeConfigId, imageData));
55+
// ipcMain.handle('trees.postImport', (_event, treeLayerId, treeConfigId, imageData) => project.postImportTree(treeLayerId, treeConfigId, imageData));
5656
ipcMain.handle('trees.remove', (_event, treeLayerId, treeConfigId) => project.removeTreeConfig(treeLayerId, treeConfigId));
5757

5858

src/lib/lidar.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,17 @@ export async function downloadCourse(geoJSON, bounds) {
259259
multiplier: 3.0,
260260
},
261261
// make sure to assign missing data before SMRF filter
262-
{
263-
type: 'filters.assign',
264-
value: [
265-
'ReturnNumber = 1 WHERE ReturnNumber == 0',
266-
'NumberOfReturns = 1 WHERE NumberOfReturns == 0'
267-
]
268-
},
262+
// {
263+
// type: 'filters.assign',
264+
// value: [
265+
// 'ReturnNumber = 1 WHERE ReturnNumber == 0',
266+
// 'NumberOfReturns = 1 WHERE NumberOfReturns == 0'
267+
// ]
268+
// },
269269
// Classify ground, but preserve existing classifications
270270
{
271271
type: 'filters.smrf',
272-
ignore: 'Classification[2:2],Classification[6:6],Classification[9:9],Classification[10:11]'
272+
// ignore: 'Classification[2:2],Classification[6:6],Classification[9:9],Classification[10:11]'
273273
},
274274
{
275275
type: 'filters.range',

src/lib/project.js

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { broadcast, mainWindow } from './window';
77
import { ensureRecent } from './app';
88
import { generateSVG, geoJSONToSvgPaths, parseSVG } from './svg';
99
import { parseRaw } from './heightmap';
10+
import { getHeightMapStats } from './terrain';
1011
import { layerToMesh, smoothTerrain, svgToCourseLayers } from './workers';
1112
import { IMAGERY_DIR, PROJECT_FILE_PROTOCOL, TERRAIN_DIR, TREE_IMPORT_PREFIX } from '../constants';
1213
import { getDateId } from './utils';
@@ -156,8 +157,8 @@ export async function saveHeightMap(heightMapData, heightScale) {
156157
// recalculate stats
157158
openProject.stats = { ...openProject.stats, ...getHeightMapStats(heightMapData, heightScale) };
158159
await saveProjectSettings();
159-
160-
_heightMapCache = { data: heightMapData, size: heightMapData.byteLength };
160+
await refreshRawData();
161+
// _heightMapCache = { data: heightMapData, size: heightMapData.byteLength };
161162
return openProject;
162163
}
163164

@@ -308,6 +309,15 @@ export async function loadProjectFile(filePath) {
308309
...stored,
309310
holes
310311
});
312+
313+
// migrate tree configs to have filenames
314+
openProject.trees.forEach(treeLayer => {
315+
treeLayer.treeConfigs.forEach(config => {
316+
if (!config.name) {
317+
config.name = path.basename(config.filePath);
318+
}
319+
});
320+
});
311321
// openProject = {
312322
// name: filePathInfo.name,
313323
// _dirty: false,
@@ -489,7 +499,7 @@ export async function generateMeshes(layerSettings, terrainSettings) {
489499
// meshMap.set(layer.id, mesh);
490500
// console.log(`Meshing ${index} of ${result.layers.length} (triangles:${mesh.triangles.length}, points:${mesh.points.length})`);
491501
meshData.meshes.set(layer.id, { name: layer.name, mesh });
492-
// console.log(`Conformed (${layer.id}) ${index} of ${result.layers.length} (triangles:${mesh.triangles.length}, points:${mesh.points.length})`);
502+
console.log(`Conformed (${layer.id}) ${index} of ${openProject._meshes.length} (triangles:${mesh.triangles.length}, points:${mesh.points.length})`);
493503

494504
progress = (index / openProject._meshes.length) * 100;
495505
index++;
@@ -604,32 +614,32 @@ export async function removeTreeConfig(treeLayerId, treeConfigId) {
604614
return openProject;
605615
}
606616

607-
export async function postImportTree(treeLayerId, treeConfigId, billboardData) {
608-
const foundLayer = openProject.trees.find(tl => tl.id === treeLayerId);
609-
const foundConfig = foundLayer.treeConfigs.find(cfg => cfg.id === treeConfigId);
610-
// write file data to disk
611-
const imageryFolder = path.join(openProject._workingDir, IMAGERY_DIR);
612-
// if (!fs.existsSync(imageryFolder)) {
613-
// fs.mkdirSync(imageryFolder);
614-
// }
615-
const billboardFilename = `tree-${treeConfigId}.png`;
616-
const outputTexture = path.join(imageryFolder, billboardFilename);
617-
let outputData;
618-
if (typeof billboardData.buffer === 'string') {
619-
outputData = Buffer.from(billboardData.buffer.split('base64,')[1], 'base64');
620-
}
621-
if (outputData) {
622-
console.log(`Writing file: ${outputTexture}`, outputData);
623-
await fs.promises.writeFile(outputTexture, outputData);
624-
foundConfig.billboard = {
625-
size: billboardData.size,
626-
filePath: outputTexture,
627-
uri: `${PROJECT_FILE_PROTOCOL}:///${path.join(IMAGERY_DIR, billboardFilename)}`
628-
};
629-
}
630-
await saveProjectSettings();
631-
return openProject.trees;
632-
}
617+
// export async function postImportTree(treeLayerId, treeConfigId, billboardData) {
618+
// const foundLayer = openProject.trees.find(tl => tl.id === treeLayerId);
619+
// const foundConfig = foundLayer.treeConfigs.find(cfg => cfg.id === treeConfigId);
620+
// // write file data to disk
621+
// const imageryFolder = path.join(openProject._workingDir, IMAGERY_DIR);
622+
// // if (!fs.existsSync(imageryFolder)) {
623+
// // fs.mkdirSync(imageryFolder);
624+
// // }
625+
// const billboardFilename = `tree-${treeConfigId}.png`;
626+
// const outputTexture = path.join(imageryFolder, billboardFilename);
627+
// let outputData;
628+
// if (typeof billboardData.buffer === 'string') {
629+
// outputData = Buffer.from(billboardData.buffer.split('base64,')[1], 'base64');
630+
// }
631+
// if (outputData) {
632+
// console.log(`Writing file: ${outputTexture}`, outputData);
633+
// await fs.promises.writeFile(outputTexture, outputData);
634+
// foundConfig.billboard = {
635+
// size: billboardData.size,
636+
// filePath: outputTexture,
637+
// uri: `${PROJECT_FILE_PROTOCOL}:///${path.join(IMAGERY_DIR, billboardFilename)}`
638+
// };
639+
// }
640+
// await saveProjectSettings();
641+
// return openProject.trees;
642+
// }
633643

634644
export async function importTree(treeLayerId) {
635645
const { canceled, filePaths } = await dialog.showOpenDialog({
@@ -643,6 +653,7 @@ export async function importTree(treeLayerId) {
643653
const config = {
644654
url: `${PROJECT_FILE_PROTOCOL}://${TREE_IMPORT_PREFIX}/${treeConfigId}.glb`,
645655
filePath: filePaths[0],
656+
name: path.basename(filePaths[0]),
646657
id: treeConfigId,
647658
randomSeed: 12345,
648659
scaleRange: { min: 0.6, max: 1.8 },

src/lib/settings.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export const defaultSettings = {
9393
blend: 0.5,
9494
// blending: { enabled: true, distance: 0.2, spacing: 0.5 },
9595
blending: { ...defaultBlend },
96-
dig: { enabled: true, depth: 5, distance: 0.3, curve: 'bezier', curvePoints: [[0, 1], [0.05, 1], [0.5, 0], [1, 0]] }
96+
dig: { enabled: true, depth: 6, distance: 0.1, curve: 'bezier', curvePoints: [[0, 1], [0.05, 1], [0.5, 0], [1, 0]] }
9797
},
9898
river: {
9999
spacing: 0.25,
@@ -133,10 +133,12 @@ export const defaultSettings = {
133133
dig: { ...defaultDig }
134134
},
135135
pine_straw: {
136-
spacing: 5,
136+
spacing: 1,
137137
// spacingEdge: 0,
138-
blend: 0,
139-
blending: { ...defaultBlend },
138+
// blend: 0,
139+
// blending: { ...defaultBlend },
140+
blend: 0.5,
141+
blending: { enabled: true, distance: 2, spacing: 0.5 },
140142
dig: { ...defaultDig }
141143
}
142144
}

0 commit comments

Comments
 (0)