{
    "id": "portable-device-charging-dock-b175a5",
    "title": "Portable Device Charging Dock",
    "class": "prop",
    "triangles": 882,
    "kit": "chronos-hearth-kit-4827fd",
    "free": true,
    "plan": "free",
    "price_usd": 0,
    "price_note": "free: every low poly model is. The /cdn links need no account and no key (an account adds the ready-to-serve zip). The HD edition, where `hd` is not null, comes with Pro",
    "owned": true,
    "page": "https://polyfork.dev/asset/portable-device-charging-dock-b175a5",
    "thumbnail": "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/hero.png",
    "preview_glb": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5-preview.glb",
    "hd": {
        "plan": "pro",
        "page": "https://polyfork.dev/asset/portable-device-charging-dock-b175a5?edition=hd",
        "kind": "its own high poly program with pbr materials",
        "triangles": 2652,
        "preview_glb": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5-hd-preview.glb",
        "files": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5-hd.zip (Pro, with a key)"
    },
    "preview_triangles": 882,
    "preview_fidelity": 1,
    "preview_rigged": true,
    "preview_rig": "pivots",
    "preview_pivots": [
        "turntable-l",
        "boom-lower-l",
        "boom-upper-l",
        "claw-l",
        "turntable-r",
        "boom-lower-r",
        "boom-upper-r",
        "claw-r"
    ],
    "preview_note": "This preview keeps its pivots named (preview_pivots), so they turn as rigged_parts describes; its normals are stripped for flat shading. This model is free, so build with `download.glb`: the authored file, normals and node names as built.",
    "has_rig": true,
    "remixable": true,
    "has_night": true,
    "has_decals": true,
    "has_ik": true,
    "ik_type": "arm",
    "has_skeleton": false,
    "size_m": {
        "x": 0.8,
        "y": 0.34,
        "z": 0.6
    },
    "origin_y": 0,
    "mass_kg": 30,
    "download": {
        "glb": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5.glb",
        "mjs": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5.mjs",
        "auth": "none"
    },
    "export_formats": {
        "fbx": {
            "url": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5.fbx",
            "for": "Unity, Unreal, Maya, 3ds Max",
            "available": true
        },
        "usdz": {
            "url": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5.usdz",
            "for": "iOS AR Quick Look, Omniverse; with UsdPhysics collision and mass",
            "available": true
        },
        "usda": {
            "url": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5.usda",
            "for": "Isaac Sim, Omniverse, Blender, usdview; with UsdPhysics collision and mass",
            "available": true
        },
        "obj": {
            "url": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5.obj",
            "for": "universal, geometry only, no pivots",
            "available": true,
            "also_fetch": "https://polyfork.dev/dl/portable-device-charging-dock-b175a5.mtl",
            "also_fetch_note": "save it beside the .obj as portable-device-charging-dock-b175a5.mtl: the model names that exact file and imports white without it"
        }
    },
    "export_note": "vertex colours become NAMED MATERIALS on export, named after this asset's own colour knobs; a plain format conversion would arrive white, because only three.js reads our COLOR_0. Built on first request (about a second), cached after. This model is free: these download with no account and no key (only its .mjs source asks for a free account).",
    "night": {
        "lens": {
            "color": "#4cd4ba",
            "intensity": 0.8,
            "albedo": "#4cd4ba",
            "findable": true,
            "describe": "Cyan energy: the power crystal in its front-left socket, the charge lamp lenses on the front rail (one lit when idle, all three while charging) and the seated core fragments while charging."
        },
        "fault": {
            "color": "#d8b067",
            "intensity": 0.7,
            "albedo": null,
            "findable": false,
            "describe": "Amber lamp lenses and seated core fragments, present only in the fault state."
        }
    },
    "night_note": "each zone is found by its ALBEDO in COLOR_0: match those vertices exactly, make them emissive at the zone colour and intensity, and drop your scene lights. That is the whole night look. NOT fault: that colour is not in this asset's geometry as it ships (default settings), so there is nothing to match and the zone cannot be lit this way. Skip it rather than guessing at a nearby colour.",
    "decals": [
        {
            "name": "maker-plate",
            "size": [
                0.24,
                0.07
            ],
            "at": [
                0,
                0.172,
                -0.235
            ],
            "normal": [
                0,
                0,
                -1
            ],
            "describe": "Flat rear face of the socket housing, where a maker or faction plate would be riveted."
        }
    ],
    "decals_note": "flat areas you can print your own logo, sign, number or stencil on. `at` is the centre in model space (metres), `normal` points out of the surface, `up` is which way is up in the artwork, `size` is [width, height]. In three.js: bake art with https://polyfork.dev/cdn/sdf.mjs and place it with https://polyfork.dev/cdn/decal.mjs. In any other engine, a `plate` area takes a quad at `at` + `normal` * 0.002; a `projected` area is on a curved face `relief_mm` deep and the mark has to be projected onto the geometry. `albedo` is the colour of the surface underneath, so you can pick art that contrasts. Measured on the DEFAULT build: a geometry knob (a remix, a get_variant result) can move the surface by a few centimetres, and decal.mjs follows it because it raycasts the model you hand it; anywhere else, re-measure or keep the defaults.",
    "params_url": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5-params.json",
    "real_scale": null,
    "physics": {
        "mass_kg": 30,
        "mass_source": "estimated",
        "material": "wood",
        "body": "dynamic",
        "dimensions_m": {
            "x": 0.8,
            "y": 0.341,
            "z": 0.6
        },
        "up_axis": "Y",
        "meters_per_unit": 1,
        "volume_m3": 0.059979,
        "collision": {
            "approximation": "convexDecomposition",
            "parts": 17,
            "colliders_url": "https://polyfork.dev/cdn/portable-device-charging-dock-b175a5-colliders.json"
        },
        "note": "For the default knob settings; a size knob changes all of it. dimensions_m and the colliders are measured from the model; mass_kg and material are an estimate of what the real object weighs. body \"static\" means fixed in place (give it a collider, no rigid body); \"dynamic\" means it moves. collision.approximation uses UsdPhysics terms: \"convexHull\" = one hull is a good fit, \"convexDecomposition\" = use the per-part hulls in colliders_url (the one hull would fill a gap, like the space under a table). Model space, metres, Y up, origin as the model ships."
    },
    "simready_metadata": {
        "simready_metadata_mass": 30,
        "simready_metadata_rigid_body_count": 1,
        "usd_dimensions": [
            0.8,
            0.6,
            0.341
        ],
        "usd_up_axis": "Z",
        "usd_meters_per_unit": 1,
        "simready_metadata_validation__profile": null
    },
    "materials": 1,
    "draw_calls": 11,
    "description": "0.8x0.6m empty bench dock with two adjustable contact arms, detachable cable and three small charge lamps. Scrap alloy on an insulated timber base. Idle/charging/fault states; named device and power sockets. No energy core, field generator or portal.",
    "palette": [
        {
            "hex": "#8b8273",
            "share": 0.469
        },
        {
            "hex": "#a79784",
            "share": 0.175
        },
        {
            "hex": "#384442",
            "share": 0.172
        },
        {
            "hex": "#996c41",
            "share": 0.066
        },
        {
            "hex": "#4cd4ba",
            "share": 0.045
        },
        {
            "hex": "#8d6640",
            "share": 0.034
        }
    ],
    "style": "low-poly, flat-shaded vertex colors, no textures, single shared material, so any set of these merges to one draw call; shares palette and scale with its kit",
    "origin": "ground level (minY = 0): the model sits on y=0 as-is",
    "rigged_parts": {
        "turntable-l": {
            "axis": "y",
            "range": [
                0,
                35
            ]
        },
        "turntable-r": {
            "axis": "y",
            "range": [
                0,
                -35
            ]
        },
        "boom-lower-l": {
            "axis": "x",
            "range": [
                0,
                -35
            ]
        },
        "boom-upper-l": {
            "axis": "x",
            "range": [
                0,
                -50
            ]
        },
        "boom-lower-r": {
            "axis": "x",
            "range": [
                0,
                -35
            ]
        },
        "boom-upper-r": {
            "axis": "x",
            "range": [
                0,
                -50
            ]
        },
        "claw-l": {
            "axis": "z",
            "range": [
                0,
                90
            ]
        },
        "claw-r": {
            "axis": "z",
            "range": [
                0,
                90
            ]
        }
    },
    "detachable_parts": [
        "crystal",
        "fragment-l",
        "fragment-r"
    ],
    "animation": "rigged parts are named groups with the pivot at the hinge/axle: obj.getObjectByName(part) then rotation[axis] (rotate, degrees) or position[axis] (slide, meters). 0 is the pose the model is built in, which is not always shut: `range` is all the travel the part has from there, and outside it the part passes through the body. Whether the range opens or closes is in that knob's describe in params_url",
    "detaching": "detachable parts are named groups you may hide or remove: obj.getObjectByName(part).visible = false, or .removeFromParent(). The surface behind each is closed, so nothing shows a hole",
    "arm": {
        "slew": "turntable-l",
        "joints": [
            "boom-lower-l",
            "boom-upper-l"
        ],
        "upper": 0.17,
        "lower": 0.12,
        "tip": [
            0,
            -0.06,
            0.104
        ],
        "tip_rest": [
            -0.262,
            0.248,
            0.089
        ],
        "base": [
            -0.28,
            0.139,
            -0.175
        ],
        "reach": 0.29,
        "stays": [],
        "axes": {
            "slew": "y",
            "joints": "x"
        },
        "units": "metres, radians",
        "runtime": "https://polyfork.dev/cdn/walk.mjs",
        "note": "two-link chain with a slew: the same solver the legged machines use. Joint ranges in `rig` are the real limits and the tip stops at them.",
        "how": "a slew and a two-link boom: aim the tip and solve, stopping at the joint ranges in rigged_parts. three.js users import https://polyfork.dev/cdn/walk.mjs and call arm(model, { rig, detach }).reachTo(point), where rig and detach are the asset module's own exports (import { createAsset, rig, detach } from the .mjs): the arm cannot find its joints without them"
    },
    "published_at": "2026-11-05 14:12:19",
    "renders": [
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/back.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/close.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/compare.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/detail.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/front.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/hero-crop.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/hero.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/left.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/low-back.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/low.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-boom-lower-l.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-boom-lower-r.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-boom-upper-l.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-boom-upper-r.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-claw-l.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-claw-r.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-turntable-l.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/pose-turntable-r.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/proofs.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/removed-crystal.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/removed-fragment-l.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/right.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/top.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/under.png",
        "https://polyfork.dev/files/portable-device-charging-dock-b175a5/renders/views.png"
    ],
    "license": "Mesh files (GLB, FBX, USD, OBJ): CC BY 4.0 with the line in `credit`, or the Polyfork licence with no credit and no redistribution, your choice. The .mjs source and the HD edition: Polyfork licence only, commercial use, no attribution, no redistribution. https://polyfork.dev/licensing",
    "credit": "Portable Device Charging Dock by Polyfork (https://polyfork.dev/asset/portable-device-charging-dock-b175a5), CC BY 4.0",
    "access": {
        "as": "anonymous",
        "remix_bakes_per_hour": 40,
        "remix_bakes_left_this_hour": 40,
        "remix_note": "The budget is on generating NEW geometry. Variations anyone has already baked are served to everybody and never counted, so re-fetching a variant you or anyone else has made costs nothing.",
        "remix_bakes_per_month": 100,
        "remix_bakes_left_this_month": 100,
        "remix_allowance_resets": "2026-12-01",
        "remix_allowance_note": "Anonymous callers are counted per IP address, so other sessions from the same address share this. A free account raises it to 300 a WEEK on its own budget, and costs an email address.",
        "a_free_account_adds": {
            "how": "Authorization: Bearer <key>, created at https://polyfork.dev/account. Costs an email address.",
            "remix_bakes_per_hour": 100,
            "remix_bakes_per_week": 300,
            "downloads": "every low poly model's .mjs program and a ready-to-serve zip from /dl, and any kit as one zip (/dl/kit-<id>.zip). The .glb, .fbx, .usdz, .usda and .obj need no key"
        },
        "pro_adds": {
            "url": "https://polyfork.dev/pricing",
            "usd_per_year": 149,
            "hd_editions": "the HD edition of a model: the same program built finer, high poly with PBR materials generated in code, every knob still working. 1,824 models have one. Free accounts get its public preview (/cdn/<id>-hd-preview.glb) only",
            "cdn": "a per-account /c/<token>/ path for the HD files you can hotlink from a shipped build; it keeps up when an asset is rebuilt, and the token is not the API key",
            "remix_bakes_per_hour": 900,
            "remix_bakes_per_week": "uncapped: a free account gets a weekly allowance, Pro does not"
        }
    }
}
