001/* 002 * Renderer 9. The MIT License. 003 * Copyright (c) 2022 rlkraft@pnw.edu 004 * See LICENSE for details. 005*/ 006 007package renderer.pipeline; 008 009import renderer.scene.*; 010 011import java.util.List; 012import java.util.ArrayList; 013 014/** 015 Transform each {@link Vertex} of a {@link Model} from the 016 {@link Camera}'s (shared) view coordinates to normalized 017 camera coordinates. 018<p> 019 This stage transforms the {@link Camera}'s view volume 020 from a user defined shape (in the view coordinate system) 021 into the standard normalized view volume (in the camera 022 coordinate system) used by the {@link Clip} pipeline stage. 023<p> 024 There are two standard normalized view volumes, one for 025 perspective projection and one for orthographic projection. 026<p> 027 The standard normalized perspective view volume is the infinitely 028 long pyramid with its apex at the origin and intersecting the 029 image plane {@code z = -1} at the corners {@code (-1, -1, -1)} 030 and {@code (+1, +1, -1)}. 031<p> 032 The standard normalized orthographic view volume is the infinitely 033 long parallelepiped centered on the z-axis and intersecting the 034 image plane {@code z = -1} at the corners {@code (-1, -1, -1)} 035 and {@code (+1, +1, -1)}. 036<p> 037 The user defined view volume determined by the {@link Scene}'s 038 {@link Camera} object is either the infinitely long pyramid with its 039 apex at the origin and intersecting the image plane {@code z = -1} at 040 the corners {@code (left, bottom, -1)} and {@code (right, top, -1)}, 041 or it is the infinitely long parallelepiped parallel to the z-axis 042 and intersecting the image plane {@code z = -1} at the corners 043 {@code (left, bottom, -1)} and {@code (right, top, -1)}. 044<p> 045 The view coordinate system is relative to the user defined view volume. 046<p> 047 The normalized camera coordinate system is relative to the normalized 048 view volume. 049<p> 050 The matrix that transforms the user defined view volume into the 051 normalized view volume also transform the view coordinate system 052 into the normalized camera coordinate system. 053<p> 054 The matrix that transforms view coordinates into normalized camera 055 coordinates is derived in the comments of 056 {@link PerspectiveNormalizeMatrix} and 057 {@link OrthographicNormalizeMatrix}. 058*/ 059public final class View2Camera 060{ 061 /** 062 Use the {@link Camera}'s normalizing {@link Matrix} to transform each 063 {@link Vertex} from the {@link Camera}'s view coordinate system to the 064 normalized camera coordinate system. 065 066 @param model {@link Model} with {@link Vertex} objects in the camera's view coordinate system 067 @param camera the {@link Scene}'s {@link Camera} with the normalizing {@link Matrix} 068 @return a new {@link Model} with {@link Vertex} objects in the normalized camera coordinate system 069 */ 070 public static Model view2camera(final Model model, final Camera camera) 071 { 072 final Matrix normalizeMatrix = camera.getNormalizeMatrix(); 073 074 // A new vertex list to hold the transformed vertices. 075 final List<Vertex> newVertexList = 076 new ArrayList<>(model.vertexList.size()); 077 078 // Replace each Vertex object with one that 079 // contains normalized camera coordinates. 080 for (final Vertex v : model.vertexList) 081 { 082 newVertexList.add( normalizeMatrix.times(v) ); 083 } 084 085 return new Model(newVertexList, 086 model.primitiveList, 087 model.colorList, 088 model.name, 089 model.visible); 090 } 091 092 093 094 // Private default constructor to enforce noninstantiable class. 095 // See Item 4 in "Effective Java", 3rd Ed, Joshua Bloch. 096 private View2Camera() { 097 throw new AssertionError(); 098 } 099}