surface placement

This commit is contained in:
wass08
2026-02-18 16:26:17 +09:00
parent c0676f684e
commit e8fcc840d5
7 changed files with 12 additions and 9 deletions
@@ -11,12 +11,12 @@ function getInitialState(node: {
}): PlacementState { }): PlacementState {
const attachTo = node.asset.attachTo const attachTo = node.asset.attachTo
if (attachTo === 'wall' || attachTo === 'wall-side') { if (attachTo === 'wall' || attachTo === 'wall-side') {
return { surface: 'wall', wallId: node.parentId, ceilingId: null } return { surface: 'wall', wallId: node.parentId, ceilingId: null, surfaceItemId: null }
} }
if (attachTo === 'ceiling') { if (attachTo === 'ceiling') {
return { surface: 'ceiling', wallId: null, ceilingId: node.parentId } return { surface: 'ceiling', wallId: null, ceilingId: node.parentId, surfaceItemId: null }
} }
return { surface: 'floor', wallId: null, ceilingId: null } return { surface: 'floor', wallId: null, ceilingId: null, surfaceItemId: null }
} }
export const MoveTool: React.FC = () => { export const MoveTool: React.FC = () => {
@@ -73,7 +73,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
const basePlaneRef = useRef<Mesh>(null!) const basePlaneRef = useRef<Mesh>(null!)
const gridPosition = useRef(new Vector3(0, 0, 0)) const gridPosition = useRef(new Vector3(0, 0, 0))
const placementState = useRef<PlacementState>( const placementState = useRef<PlacementState>(
config.initialState ?? { surface: 'floor', wallId: null, ceilingId: null }, config.initialState ?? { surface: 'floor', wallId: null, ceilingId: null, surfaceItemId: null },
) )
const shiftFreeRef = useRef(false) const shiftFreeRef = useRef(false)
@@ -1167,7 +1167,9 @@ export const CATALOG_ITEMS: AssetInput[] = [
scale: [1, 1, 1], scale: [1, 1, 1],
offset: [0, 0.21, 0], offset: [0, 0.21, 0],
rotation: [0, 0, 0], rotation: [0, 0, 0],
dimensions: [2, 0.4, 0.5], dimensions: [2, 0.4, 0.5],surface: {
height: 0.36
}
}, },
{ {
@@ -1,4 +1,4 @@
import { ItemNode } from "@pascal-app/core"; import { type AnyNodeId, ItemNode } from "@pascal-app/core";
import { useViewer } from "@pascal-app/viewer"; import { useViewer } from "@pascal-app/viewer";
import Image from "next/image"; import Image from "next/image";
import { useState } from "react"; import { useState } from "react";
@@ -14,7 +14,8 @@ export async function submitFeedback(
const session = await getSession() const session = await getSession()
const supabase = await createServerSupabaseClient() const supabase = await createServerSupabaseClient()
const { error } = await supabase.from('feedback').insert({ // eslint-disable-next-line @typescript-eslint/no-explicit-any
const { error } = await (supabase as any).from('feedback').insert({
id: createId('feedback'), id: createId('feedback'),
user_id: session?.user?.id ?? null, user_id: session?.user?.id ?? null,
message: trimmed, message: trimmed,
+1 -1
View File
@@ -31,7 +31,7 @@ export const ItemNode = BaseNode.extend({
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]), position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
rotation: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]), rotation: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
side: z.enum(['front', 'back']).optional(), side: z.enum(['front', 'back']).optional(),
children: z.array(z.string()).default([]), children: z.array(objectId('item')).default([]),
// Wall attachment properties (only used when asset.attachTo is "wall" or "wall-side") // Wall attachment properties (only used when asset.attachTo is "wall" or "wall-side")
wallId: z.string().optional(), wallId: z.string().optional(),
@@ -45,7 +45,7 @@ export const ItemRenderer = ({ node }: { node: ItemNode }) => {
<ModelRenderer node={node} /> <ModelRenderer node={node} />
</Suspense> </Suspense>
{node.children?.map((childId) => ( {node.children?.map((childId) => (
<NodeRenderer key={childId} nodeId={childId as ItemNode['id']} /> <NodeRenderer key={childId} nodeId={childId } />
))} ))}
</group> </group>
) )